library(ggplot2)
library(dplyr)
library(stats)
True value in set1, sim1
TrueValue_set1 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_1[1, 2])), ", ")[[1]]
#average <- mean(TrueValues_set1)
plot(TrueValue_set1, type = "l", pch = 16, col = "blue", main = "True Values in sim0", xlab = "Iteration", ylab = "Value")

#TrueValue_set1_sim0 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_1[1, 2])), ", ")[[1]]
#unlist(aggregated_results_1[1, 2])
#clean_str = gsub("\\[|\\]", "", TrueValue_sim0)
#TrueValue_set1_sim1 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_1[2, 2])), ", ")[[1]]
#print(Values)
#X <- 1:100
#plot(TrueValue_set1_sim0, type = "l", pch = 16, col = "blue", main = "True Values in sim0", xlab = "Iteration", ylab = "Value")
#plot(TrueValue_set1_sim1, type = "l", pch = 16, col = "blue", main = "True Values in sim1", xlab = "Iteration", ylab = "Value")
#fit <- lm(Values ~ X)
#abline(fit, col = "red")
True values in set 1, all sim
# Initialize an empty vector to store the True values
TrueValues_set1 <- numeric()
# Loop through each iteration (n)
for (n in 1:10) {
# Extract True values from the aggregated_results_1 dataframe
TrueValue_set1 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_1[n, 2])), ", ")[[1]]
# Append the True values to the vector
TrueValues_set1 <- c(TrueValues_set1, as.numeric(TrueValue_set1))
}
# Calculate the average of True values
average <- mean(TrueValues_set1)
# Plot the average
plot(TrueValues_set1, type = "l", pch = 16, col = "blue", main = "True Values in set 1", xlab = "Iteration", ylab = "Value")
# Add a horizontal line for the average
abline(h = average, col = "red", lwd = 2)

Expected value in set1, all sim
# Initialize an empty vector to store the True values
ExpectedValues_set1 <- numeric()
# Loop through each iteration (n)
for (n in 1:10) {
# Extract True values from the aggregated_results_1 dataframe
ExpectedValue_set1 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_1[n, 3])), ", ")[[1]]
# Append the True values to the vector
ExpectedValues_set1 <- c(ExpectedValues_set1, as.numeric(ExpectedValue_set1))
}
# Calculate the average of True values
average <- mean(ExpectedValues_set1)
# Plot the average
plot(ExpectedValues_set1, type = "l", pch = 16, col = "blue", main = "Expected Values in set 1", xlab = "Iteration", ylab = "Value")
# Add a horizontal line for the average
abline(h = average, col = "red", lwd = 2)

True and Expected Values in set 1
# Initialize empty vectors to store true and expected values
TrueValues_set1 <- numeric()
ExpectedValues_set1 <- numeric()
# Loop through each iteration (n)
for (n in 1:10) {
# Extract True values from the aggregated_results_1 dataframe
TrueValue_set1 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_1[n, 2])), ", ")[[1]]
# Extract Expected values from the aggregated_results_1 dataframe
ExpectedValue_set1 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_1[n, 3])), ", ")[[1]]
# Append the True and Expected values to their respective vectors
TrueValues_set1 <- c(TrueValues_set1, as.numeric(TrueValue_set1))
ExpectedValues_set1 <- c(ExpectedValues_set1, as.numeric(ExpectedValue_set1))
}
# Calculate the average of True values
average_true <- mean(TrueValues_set1)
# Calculate the average of Expected values
average_expected <- mean(ExpectedValues_set1)
# Plot True and Expected values on the same plot
plot(TrueValues_set1, type = "l", pch = 16, col = "blue", main = "True vs Expected Values in set 1", xlab = "Iteration", ylab = "Value")
lines(ExpectedValues_set1, type = "l", pch = 16, col = "red")
# Add legend
legend("topright", legend = c("True Values", "Expected Values"), col = c("blue", "red"), lty = 1, cex = 0.8)
# Add horizontal lines for the averages
abline(h = average_true, col = "blue", lwd = 1)
abline(h = average_expected, col = "red", lwd = 1)

Bids in set1, sim1
Bids_set1 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_1[1, 4])), ", ")[[1]]
#average <- mean(TrueValues_set1)
plot(Bids_set1, type = "l", pch = 16, col = "blue", main = "True Values in sim0", xlab = "Iteration", ylab = "Value")

Bids in set 1, all sim
# Initialize an empty vector to store the True values
Bids_set1 <- numeric()
# Loop through each iteration (n)
for (n in 1:10) {
# Extract True values from the aggregated_results_1 dataframe
Bid_set1 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_1[n, 4])), ", ")[[1]]
# Append the True values to the vector (corrected typo)
Bids_set1 <- c(Bids_set1, as.numeric(Bid_set1))
}
# Check if the vector is properly populated
#print(Bids_set1)
# Calculate the average of True values
average <- mean(Bids_set1, na.rm = TRUE)
# Plot the values
plot(Bids_set1, type = "l", pch = 16, col = "blue", main = "Bid vs Ask in set 1", xlab = "Iteration", ylab = "Value")
# Add a horizontal line for the average
abline(h = average, col = "red", lwd = 2)

Bids and Asks Overall
# Initialize empty vectors to store the Bid and Ask values
Bids_set1 <- numeric()
Asks_set1 <- numeric()
# Loop through each iteration (n)
for (n in 1:10) {
# Extract Bid values from the aggregated_results_1 dataframe
Bid_set1 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_1[n, 4])), ", ")[[1]]
# Extract Ask values from the aggregated_results_1 dataframe (next column)
Ask_set1 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_1[n, 5])), ", ")[[1]]
# Append the Bid and Ask values to their respective vectors
Bids_set1 <- c(Bids_set1, as.numeric(Bid_set1))
Asks_set1 <- c(Asks_set1, as.numeric(Ask_set1))
}
# Calculate the average of Bid and Ask values
average_bids <- mean(Bids_set1, na.rm = TRUE)
average_asks <- mean(Asks_set1, na.rm = TRUE)
# Plot the Bid and Ask values on the same plot
plot(Bids_set1, type = "l", pch = 16, col = "blue", main = "Bids vs Asks in set 1", xlab = "Iteration", ylab = "Value")
lines(Asks_set1, type = "l", pch = 16, col = "red")
# Add legend
legend("topright", legend = c("Bids", "Asks"), col = c("blue", "red"), lty = 1, cex = 0.8)
# Add horizontal lines for the averages
abline(h = average_bids, col = "blue", lty = 1)
abline(h = average_asks, col = "red", lty = 1)

Start From Here
set 1 (6 informed)
# Initialize matrices to store averages for each position
average_true <- matrix(NA, nrow = 100, ncol = 10)
average_expected <- matrix(NA, nrow = 100, ncol = 10)
# Loop through each simulation (n)
for (n in 1:10) {
# Extract True values from the aggregated_results_4 dataframe
TrueValues_set1 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_1[n, 2])), ", ")
# Extract Expected values from the aggregated_results_4 dataframe
ExpectedValues_set1 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_1[n, 3])), ", ")
# Loop through each position (i)
for (i in 1:100) {
# Extract True and Expected values for the i-th position
True_values <- sapply(TrueValues_set1, function(x) as.numeric(x[i]))
Expected_values <- sapply(ExpectedValues_set1, function(x) as.numeric(x[i]))
# Calculate the average of True and Expected values for the i-th position
average_true[i, n] <- mean(True_values, na.rm = TRUE)
average_expected[i, n] <- mean(Expected_values, na.rm = TRUE)
}
}
# Calculate the overall average for each position across all simulations
overall_average_true <- rowMeans(average_true, na.rm = TRUE)
overall_average_expected <- rowMeans(average_expected, na.rm = TRUE)
# Plot the overall averages
plot(overall_average_true, type = "l", pch = 16, col = "blue", main = "Overall Average of True vs Expected Values", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_true, overall_average_expected)), max(c(overall_average_true, overall_average_expected))))
lines(overall_average_expected, type = "l", pch = 16, col = "red")
legend("topright", legend = c("True Values", "Expected Values"), col = c("blue", "red"), lty = 1, cex = 0.8)

# Initialize matrices to store averages for each position
average_bid <- matrix(NA, nrow = 100, ncol = 10)
average_ask <- matrix(NA, nrow = 100, ncol = 10)
# Loop through each simulation (n)
for (n in 1:10) {
# Extract True values from the aggregated_results_4 dataframe
Bids_set1 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_1[n, 4])), ", ")
# Extract Expected values from the aggregated_results_4 dataframe
Asks_set1 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_1[n, 5])), ", ")
# Loop through each position (i)
for (i in 1:100) {
# Extract True and Expected values for the i-th position
Bids <- sapply(Bids_set1, function(x) as.numeric(x[i]))
Asks <- sapply(Asks_set1, function(x) as.numeric(x[i]))
# Calculate the average of True and Expected values for the i-th position
average_bid[i, n] <- mean(Bids, na.rm = TRUE)
average_ask[i, n] <- mean(Asks, na.rm = TRUE)
}
}
# Calculate the overall average for each position across all simulations
overall_average_bid <- rowMeans(average_bid, na.rm = TRUE)
overall_average_ask <- rowMeans(average_ask, na.rm = TRUE)
## True Value
# Initialize matrices to store averages for each position
average_true <- matrix(NA, nrow = 100, ncol = 10)
average_expected <- matrix(NA, nrow = 100, ncol = 10)
# Loop through each simulation (n)
for (n in 1:10) {
# Extract True values from the aggregated_results_4 dataframe
TrueValues_set1 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_1[n, 2])), ", ")
# Extract Expected values from the aggregated_results_4 dataframe
ExpectedValues_set1 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_1[n, 3])), ", ")
# Loop through each position (i)
for (i in 1:100) {
# Extract True and Expected values for the i-th position
True_values <- sapply(TrueValues_set1, function(x) as.numeric(x[i]))
Expected_values <- sapply(ExpectedValues_set1, function(x) as.numeric(x[i]))
# Calculate the average of True and Expected values for the i-th position
average_true[i, n] <- mean(True_values, na.rm = TRUE)
average_expected[i, n] <- mean(Expected_values, na.rm = TRUE)
}
}
# Calculate the overall average for each position across all simulations
overall_average_true <- rowMeans(average_true, na.rm = TRUE)
overall_average_expected <- rowMeans(average_expected, na.rm = TRUE)
# Plot the overall averages
#plot(overall_average_true, type = "l", pch = 16, col = "blue", main = "Overall Average of True vs Expected Values", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_true, overall_average_expected)), max(c(overall_average_true, overall_average_expected))))
#lines(overall_average_expected, type = "l", pch = 16, col = "red")
#legend("topright", legend = c("True Values", "Expected Values"), col = c("blue", "red"), lty = 1, cex = 0.8)
# Plot the overall averages
plot(overall_average_bid, type = "l", pch = 16, col = "blue", main = "Overall Average of Bids vs Asks & True vs Expected Values", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_bid, overall_average_ask)), max(c(overall_average_bid, overall_average_ask))))
lines(overall_average_ask, type = "l", pch = 16, col = "red")
lines(overall_average_true, type = "l", pch = 16, col = "green")
lines(overall_average_expected, type = "l", pch = 16, col = "purple")
legend("topright", legend = c("Bids", "Asks", "True Value", "Expected Value"), col = c("blue", "red", "green", "purple"), lty = 1, cex = 0.8)

Pick sim 5 as a example
TrueValue_set1 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_1[5, 2])), ", ")[[1]]
Bids_set1 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_1[5, 4])), ", ")[[1]]
Asks_set1 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_1[5, 5])), ", ")[[1]]
plot(TrueValue_set1,
type = "l",
pch = 16,
col = "green",
main = "True Values in sim 5",
xlab = "Iteration",
ylab = "Value",
ylim = c(min(c(as.numeric(TrueValue_set1), as.numeric(Bids_set1), as.numeric(Asks_set1))),
max(c(as.numeric(TrueValue_set1), as.numeric(Bids_set1), as.numeric(Asks_set1)))))
lines(Bids_set1, type = "l", pch = 16, col = "blue")
lines(Asks_set1, type = "l", pch = 16, col = "red")
legend("topleft", legend = c("Bids", "Asks", "True Value"), col = c("blue", "red", "green"), lty = 1, cex = 0.8)

MM_pnl_set1 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_1[5, 6])), ", ")[[1]]
Informed1_pnl_set1 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_1[5, 8])), ", ")[[1]]
Informed2_pnl_set1 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_1[5, 10])), ", ")[[1]]
Informed3_pnl_set1 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_1[5, 12])), ", ")[[1]]
Informed4_pnl_set1 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_1[5, 14])), ", ")[[1]]
Informed5_pnl_set1 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_1[5, 16])), ", ")[[1]]
Informed6_pnl_set1 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_1[5, 18])), ", ")[[1]]
#Bids_set1 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_1[5, 4])), ", ")[[1]]
#Asks_set1 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_1[5, 5])), ", ")[[1]]
plot(MM_pnl_set1,
type = "l",
pch = 16,
col = "black",
main = "PNL sim 5",
xlab = "Position in List",
ylab = "Value",
ylim = c(min(c(as.numeric(MM_pnl_set1), as.numeric(Informed1_pnl_set1), as.numeric(Informed2_pnl_set1), as.numeric(Informed3_pnl_set1), as.numeric(Informed4_pnl_set1), as.numeric(Informed5_pnl_set1), as.numeric(Informed6_pnl_set1))),
max(c(as.numeric(MM_pnl_set1), as.numeric(Informed1_pnl_set1), as.numeric(Informed2_pnl_set1), as.numeric(Informed3_pnl_set1), as.numeric(Informed4_pnl_set1), as.numeric(Informed5_pnl_set1), as.numeric(Informed6_pnl_set1)))))
lines(Informed1_pnl_set1, type = "l", pch = 16, col = "red")
lines(Informed2_pnl_set1, type = "l", pch = 16, col = "green")
lines(Informed3_pnl_set1, type = "l", pch = 16, col = "yellow")
lines(Informed4_pnl_set1, type = "l", pch = 16, col = "blue")
lines(Informed5_pnl_set1, type = "l", pch = 16, col = "purple")
lines(Informed6_pnl_set1, type = "l", pch = 16, col = "orange")
# Add legend
legend("bottomleft", legend = c("Market Maker", "Informed 1", "Informed 2", "Informed 3", "Informed 4", "Informed 5", "Informed 6"), col = c("black", "red", "green", "yellow", "blue", "purple", "orange"), lty = 1, cex = 0.8)

MM_pnl_set1 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_1[5, 7])), ", ")[[1]]
Informed1_pnl_set1 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_1[5, 9])), ", ")[[1]]
Informed2_pnl_set1 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_1[5, 11])), ", ")[[1]]
Informed3_pnl_set1 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_1[5, 13])), ", ")[[1]]
Informed4_pnl_set1 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_1[5, 15])), ", ")[[1]]
Informed5_pnl_set1 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_1[5, 17])), ", ")[[1]]
Informed6_pnl_set1 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_1[5, 19])), ", ")[[1]]
#Bids_set1 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_1[5, 4])), ", ")[[1]]
#Asks_set1 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_1[5, 5])), ", ")[[1]]
plot(MM_pnl_set1,
type = "l",
pch = 16,
col = "black",
main = "POS in sim 5",
xlab = "Position in List",
ylab = "Value",
ylim = c(min(c(as.numeric(MM_pnl_set1), as.numeric(Informed1_pnl_set1), as.numeric(Informed2_pnl_set1), as.numeric(Informed3_pnl_set1), as.numeric(Informed4_pnl_set1), as.numeric(Informed5_pnl_set1), as.numeric(Informed6_pnl_set1))),
max(c(as.numeric(MM_pnl_set1), as.numeric(Informed1_pnl_set1), as.numeric(Informed2_pnl_set1), as.numeric(Informed3_pnl_set1), as.numeric(Informed4_pnl_set1), as.numeric(Informed5_pnl_set1), as.numeric(Informed6_pnl_set1)))))
lines(Informed1_pnl_set1, type = "l", pch = 16, col = "red")
lines(Informed2_pnl_set1, type = "l", pch = 16, col = "green")
lines(Informed3_pnl_set1, type = "l", pch = 16, col = "yellow")
lines(Informed4_pnl_set1, type = "l", pch = 16, col = "blue")
lines(Informed5_pnl_set1, type = "l", pch = 16, col = "purple")
lines(Informed6_pnl_set1, type = "l", pch = 16, col = "orange")
# Add legend
legend("bottomleft", legend = c("Market Maker", "Informed 1", "Informed 2", "Informed 3", "Informed 4", "Informed 5", "Informed 6"), col = c("black", "red", "green", "yellow", "blue", "purple", "orange"), lty = 1, cex = 0.8)

# Initialize matrices to store averages for each position
average_MM_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_Informed1_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_Informed2_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_Informed3_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_Informed4_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_Informed5_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_Informed6_pnl <- matrix(NA, nrow = 100, ncol = 10)
# Loop through each simulation (n)
for (n in 1:10) {
MM_pnl_set1 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_1[n, 6])), ", ")
Informed1_pnl_set1 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_1[n, 8])), ", ")
Informed2_pnl_set1 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_1[n, 10])), ", ")
Informed3_pnl_set1 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_1[n, 12])), ", ")
Informed4_pnl_set1 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_1[n, 14])), ", ")
Informed5_pnl_set1 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_1[n, 16])), ", ")
Informed6_pnl_set1 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_1[n, 18])), ", ")
# Loop through each position (i)
for (i in 1:100) {
# Extract True and Expected values for the i-th position
MM_pnl <- sapply(MM_pnl_set1, function(x) as.numeric(x[i]))
Informed1_pnl <- sapply(Informed1_pnl_set1, function(x) as.numeric(x[i]))
Informed2_pnl <- sapply(Informed2_pnl_set1, function(x) as.numeric(x[i]))
Informed3_pnl <- sapply(Informed3_pnl_set1, function(x) as.numeric(x[i]))
Informed4_pnl <- sapply(Informed4_pnl_set1, function(x) as.numeric(x[i]))
Informed5_pnl <- sapply(Informed5_pnl_set1, function(x) as.numeric(x[i]))
Informed6_pnl <- sapply(Informed6_pnl_set1, function(x) as.numeric(x[i]))
# Calculate the average of True and Expected values for the i-th position
average_MM_pnl[i, n] <- mean(MM_pnl, na.rm = TRUE)
average_Informed1_pnl[i, n] <- mean(Informed1_pnl, na.rm = TRUE)
average_Informed2_pnl[i, n] <- mean(Informed2_pnl, na.rm = TRUE)
average_Informed3_pnl[i, n] <- mean(Informed3_pnl, na.rm = TRUE)
average_Informed4_pnl[i, n] <- mean(Informed4_pnl, na.rm = TRUE)
average_Informed5_pnl[i, n] <- mean(Informed5_pnl, na.rm = TRUE)
average_Informed6_pnl[i, n] <- mean(Informed6_pnl, na.rm = TRUE)
}
}
# Calculate the overall average for each position across all simulations
overall_average_MM_pnl <- rowMeans(average_MM_pnl, na.rm = TRUE)
overall_average_Informed1_pnl <- rowMeans(average_Informed1_pnl, na.rm = TRUE)
overall_average_Informed2_pnl <- rowMeans(average_Informed2_pnl, na.rm = TRUE)
overall_average_Informed3_pnl <- rowMeans(average_Informed3_pnl, na.rm = TRUE)
overall_average_Informed4_pnl <- rowMeans(average_Informed4_pnl, na.rm = TRUE)
overall_average_Informed5_pnl <- rowMeans(average_Informed5_pnl, na.rm = TRUE)
overall_average_Informed6_pnl <- rowMeans(average_Informed6_pnl, na.rm = TRUE)
# Plot the overall averages
plot(overall_average_MM_pnl, type = "l", pch = 16, col = "black", main = "Overall Average PNL", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_MM_pnl, overall_average_Informed1_pnl, overall_average_Informed2_pnl, overall_average_Informed3_pnl, overall_average_Informed4_pnl, overall_average_Informed5_pnl, overall_average_Informed6_pnl)), max(c(overall_average_MM_pnl, overall_average_Informed1_pnl, overall_average_Informed2_pnl, overall_average_Informed3_pnl, overall_average_Informed4_pnl, overall_average_Informed5_pnl, overall_average_Informed6_pnl))))
lines(overall_average_Informed1_pnl, type = "l", pch = 16, col = "red")
lines(overall_average_Informed2_pnl, type = "l", pch = 16, col = "green")
lines(overall_average_Informed3_pnl, type = "l", pch = 16, col = "yellow")
lines(overall_average_Informed4_pnl, type = "l", pch = 16, col = "blue")
lines(overall_average_Informed5_pnl, type = "l", pch = 16, col = "purple")
lines(overall_average_Informed6_pnl, type = "l", pch = 16, col = "orange")
# Add legend
legend("bottomleft", legend = c("Market Maker", "Informed 1", "Informed 2", "Informed 3", "Informed 4", "Informed 5", "Informed 6"), col = c("black", "red", "green", "yellow", "blue", "purple", "orange"), lty = 1, cex = 0.8)

# Initialize matrices to store averages for each position
average_MM_pos <- matrix(NA, nrow = 100, ncol = 10)
average_Informed1_pos <- matrix(NA, nrow = 100, ncol = 10)
average_Informed2_pos <- matrix(NA, nrow = 100, ncol = 10)
average_Informed3_pos <- matrix(NA, nrow = 100, ncol = 10)
average_Informed4_pos <- matrix(NA, nrow = 100, ncol = 10)
average_Informed5_pos <- matrix(NA, nrow = 100, ncol = 10)
average_Informed6_pos <- matrix(NA, nrow = 100, ncol = 10)
# Loop through each simulation (n)
for (n in 1:10) {
MM_pos_set1 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_1[n, 7])), ", ")
Informed1_pos_set1 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_1[n, 9])), ", ")
Informed2_pos_set1 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_1[n, 11])), ", ")
Informed3_pos_set1 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_1[n, 13])), ", ")
Informed4_pos_set1 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_1[n, 15])), ", ")
Informed5_pos_set1 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_1[n, 17])), ", ")
Informed6_pos_set1 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_1[n, 19])), ", ")
# Loop through each position (i)
for (i in 1:100) {
# Extract True and Expected values for the i-th position
MM_pos <- sapply(MM_pos_set1, function(x) as.numeric(x[i]))
Informed1_pos <- sapply(Informed1_pos_set1, function(x) as.numeric(x[i]))
Informed2_pos <- sapply(Informed2_pos_set1, function(x) as.numeric(x[i]))
Informed3_pos <- sapply(Informed3_pos_set1, function(x) as.numeric(x[i]))
Informed4_pos <- sapply(Informed4_pos_set1, function(x) as.numeric(x[i]))
Informed5_pos <- sapply(Informed5_pos_set1, function(x) as.numeric(x[i]))
Informed6_pos <- sapply(Informed6_pos_set1, function(x) as.numeric(x[i]))
# Calculate the average of True and Expected values for the i-th position
average_MM_pos[i, n] <- mean(MM_pos, na.rm = TRUE)
average_Informed1_pos[i, n] <- mean(Informed1_pos, na.rm = TRUE)
average_Informed2_pos[i, n] <- mean(Informed2_pos, na.rm = TRUE)
average_Informed3_pos[i, n] <- mean(Informed3_pos, na.rm = TRUE)
average_Informed4_pos[i, n] <- mean(Informed4_pos, na.rm = TRUE)
average_Informed5_pos[i, n] <- mean(Informed5_pos, na.rm = TRUE)
average_Informed6_pos[i, n] <- mean(Informed6_pos, na.rm = TRUE)
}
}
# Calculate the overall average for each position across all simulations
overall_average_MM_pos <- rowMeans(average_MM_pos, na.rm = TRUE)
overall_average_Informed1_pos <- rowMeans(average_Informed1_pos, na.rm = TRUE)
overall_average_Informed2_pos <- rowMeans(average_Informed2_pos, na.rm = TRUE)
overall_average_Informed3_pos <- rowMeans(average_Informed3_pos, na.rm = TRUE)
overall_average_Informed4_pos <- rowMeans(average_Informed4_pos, na.rm = TRUE)
overall_average_Informed5_pos <- rowMeans(average_Informed5_pos, na.rm = TRUE)
overall_average_Informed6_pos <- rowMeans(average_Informed6_pos, na.rm = TRUE)
# Plot the overall averages
plot(overall_average_MM_pos, type = "l", pch = 16, col = "black", main = "Overall Average Position", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_MM_pos, overall_average_Informed1_pos, overall_average_Informed2_pos, overall_average_Informed3_pos, overall_average_Informed4_pos, overall_average_Informed5_pos, overall_average_Informed6_pos)), max(c(overall_average_MM_pos, overall_average_Informed1_pos, overall_average_Informed2_pos, overall_average_Informed3_pos, overall_average_Informed4_pos, overall_average_Informed5_pos, overall_average_Informed6_pos))))
#for (i in seq_along(overall_average_MM_pos)) {
#if (overall_average_MM_pos[i] != 0) {
#points(i, overall_average_MM_pos[i], col = "red", pch = 16)
#}
#}
#points(overall_average_MM_pos, col = "red", pch = 16)
lines(overall_average_Informed1_pos, type = "l", pch = 16, col = "red")
lines(overall_average_Informed2_pos, type = "l", pch = 16, col = "green")
lines(overall_average_Informed3_pos, type = "l", pch = 16, col = "yellow")
lines(overall_average_Informed4_pos, type = "l", pch = 16, col = "blue")
lines(overall_average_Informed5_pos, type = "l", pch = 16, col = "purple")
lines(overall_average_Informed6_pos, type = "l", pch = 16, col = "orange")
# Add legend
legend("bottomleft", legend = c("Market Maker", "Informed 1", "Informed 2", "Informed 3", "Informed 4", "Informed 5", "Informed 6"), col = c("black", "red", "green", "yellow", "blue", "purple", "orange"), lty = 1, cex = 0.8)

set 2 (1 Informed + 1 noisy informed + 1 noisy + 1 stochastic noisy
+ 1 mr + 1 mom)
# Initialize matrices to store averages for each position
average_true <- matrix(NA, nrow = 100, ncol = 10)
average_expected <- matrix(NA, nrow = 100, ncol = 10)
# Loop through each simulation (n)
for (n in 1:10) {
# Extract True values from the aggregated_results_4 dataframe
TrueValues_set2 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_2[n, 2])), ", ")
# Extract Expected values from the aggregated_results_4 dataframe
ExpectedValues_set2 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_2[n, 3])), ", ")
# Loop through each position (i)
for (i in 1:100) {
# Extract True and Expected values for the i-th position
True_values <- sapply(TrueValues_set2, function(x) as.numeric(x[i]))
Expected_values <- sapply(ExpectedValues_set2, function(x) as.numeric(x[i]))
# Calculate the average of True and Expected values for the i-th position
average_true[i, n] <- mean(True_values, na.rm = TRUE)
average_expected[i, n] <- mean(Expected_values, na.rm = TRUE)
}
}
# Calculate the overall average for each position across all simulations
overall_average_true <- rowMeans(average_true, na.rm = TRUE)
overall_average_expected <- rowMeans(average_expected, na.rm = TRUE)
# Plot the overall averages
plot(overall_average_true, type = "l", pch = 16, col = "blue", main = "Overall Average of True vs Expected Values", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_true, overall_average_expected)), max(c(overall_average_true, overall_average_expected))))
lines(overall_average_expected, type = "l", pch = 16, col = "red")
legend("topright", legend = c("True Values", "Expected Values"), col = c("blue", "red"), lty = 1, cex = 0.8)

# Initialize matrices to store averages for each position
average_bid <- matrix(NA, nrow = 100, ncol = 10)
average_ask <- matrix(NA, nrow = 100, ncol = 10)
# Loop through each simulation (n)
for (n in 1:10) {
# Extract True values from the aggregated_results_4 dataframe
Bids_set2 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_2[n, 4])), ", ")
# Extract Expected values from the aggregated_results_4 dataframe
Asks_set2 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_2[n, 5])), ", ")
# Loop through each position (i)
for (i in 1:100) {
# Extract True and Expected values for the i-th position
Bids <- sapply(Bids_set2, function(x) as.numeric(x[i]))
Asks <- sapply(Asks_set2, function(x) as.numeric(x[i]))
# Calculate the average of True and Expected values for the i-th position
average_bid[i, n] <- mean(Bids, na.rm = TRUE)
average_ask[i, n] <- mean(Asks, na.rm = TRUE)
}
}
# Calculate the overall average for each position across all simulations
overall_average_bid <- rowMeans(average_bid, na.rm = TRUE)
overall_average_ask <- rowMeans(average_ask, na.rm = TRUE)
# Plot the overall averages
plot(overall_average_bid, type = "l", pch = 16, col = "blue", main = "Overall Average of Bids vs Asks", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_bid, overall_average_ask)), max(c(overall_average_bid, overall_average_ask))))
lines(overall_average_ask, type = "l", pch = 16, col = "red")
legend("topright", legend = c("Bids", "Asks"), col = c("blue", "red"), lty = 1, cex = 0.8)

# Initialize matrices to store averages for each position
average_bid <- matrix(NA, nrow = 100, ncol = 10)
average_ask <- matrix(NA, nrow = 100, ncol = 10)
# Loop through each simulation (n)
for (n in 1:10) {
# Extract True values from the aggregated_results_4 dataframe
Bids_set2 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_2[n, 4])), ", ")
# Extract Expected values from the aggregated_results_4 dataframe
Asks_set2 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_2[n, 5])), ", ")
# Loop through each position (i)
for (i in 1:100) {
# Extract True and Expected values for the i-th position
Bids <- sapply(Bids_set2, function(x) as.numeric(x[i]))
Asks <- sapply(Asks_set2, function(x) as.numeric(x[i]))
# Calculate the average of True and Expected values for the i-th position
average_bid[i, n] <- mean(Bids, na.rm = TRUE)
average_ask[i, n] <- mean(Asks, na.rm = TRUE)
}
}
# Calculate the overall average for each position across all simulations
overall_average_bid <- rowMeans(average_bid, na.rm = TRUE)
overall_average_ask <- rowMeans(average_ask, na.rm = TRUE)
## True Value
# Initialize matrices to store averages for each position
average_true <- matrix(NA, nrow = 100, ncol = 10)
average_expected <- matrix(NA, nrow = 100, ncol = 10)
# Loop through each simulation (n)
for (n in 1:10) {
# Extract True values from the aggregated_results_4 dataframe
TrueValues_set2 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_2[n, 2])), ", ")
# Extract Expected values from the aggregated_results_4 dataframe
ExpectedValues_set2 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_2[n, 3])), ", ")
# Loop through each position (i)
for (i in 1:100) {
# Extract True and Expected values for the i-th position
True_values <- sapply(TrueValues_set2, function(x) as.numeric(x[i]))
Expected_values <- sapply(ExpectedValues_set2, function(x) as.numeric(x[i]))
# Calculate the average of True and Expected values for the i-th position
average_true[i, n] <- mean(True_values, na.rm = TRUE)
average_expected[i, n] <- mean(Expected_values, na.rm = TRUE)
}
}
# Calculate the overall average for each position across all simulations
overall_average_true <- rowMeans(average_true, na.rm = TRUE)
overall_average_expected <- rowMeans(average_expected, na.rm = TRUE)
# Plot the overall averages
#plot(overall_average_true, type = "l", pch = 16, col = "blue", main = "Overall Average of True vs Expected Values", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_true, overall_average_expected)), max(c(overall_average_true, overall_average_expected))))
#lines(overall_average_expected, type = "l", pch = 16, col = "red")
#legend("topright", legend = c("True Values", "Expected Values"), col = c("blue", "red"), lty = 1, cex = 0.8)
# Plot the overall averages
plot(overall_average_bid, type = "l", pch = 16, col = "blue", main = "Overall Average of Bids vs Asks & True vs Expected Values", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_bid, overall_average_ask)), max(c(overall_average_bid, overall_average_ask))))
lines(overall_average_ask, type = "l", pch = 16, col = "red")
lines(overall_average_true, type = "l", pch = 16, col = "green")
lines(overall_average_expected, type = "l", pch = 16, col = "purple")
legend("topright", legend = c("Bids", "Asks", "True Value", "Expected Value"), col = c("blue", "red", "green", "purple"), lty = 1, cex = 0.8)

# Initialize matrices to store averages for each position
average_MM_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_Informed_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_NoisyInformed_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_Noisy_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_StochNoisy_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_mr_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_mom_pnl <- matrix(NA, nrow = 100, ncol = 10)
# Loop through each simulation (n)
for (n in 1:10) {
MM_pnl_set2 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_2[n, 6])), ", ")
Informed_pnl_set2 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_2[n, 8])), ", ")
NoisyInformed_pnl_set2 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_2[n, 10])), ", ")
Noisy_pnl_set2 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_2[n, 12])), ", ")
StochNoisy_pnl_set2 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_2[n, 14])), ", ")
mr_pnl_set2 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_2[n, 16])), ", ")
mom_pnl_set2 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_2[n, 18])), ", ")
# Loop through each position (i)
for (i in 1:100) {
# Extract True and Expected values for the i-th position
MM_pnl <- sapply(MM_pnl_set2, function(x) as.numeric(x[i]))
Informed_pnl <- sapply(Informed_pnl_set2, function(x) as.numeric(x[i]))
NoisyInformed_pnl <- sapply(NoisyInformed_pnl_set2, function(x) as.numeric(x[i]))
Noisy_pnl <- sapply(Noisy_pnl_set2, function(x) as.numeric(x[i]))
StochNoisy_pnl <- sapply(StochNoisy_pnl_set2, function(x) as.numeric(x[i]))
mr_pnl <- sapply(mr_pnl_set2, function(x) as.numeric(x[i]))
mom_pnl <- sapply(mom_pnl_set2, function(x) as.numeric(x[i]))
# Calculate the average of True and Expected values for the i-th position
average_MM_pnl[i, n] <- mean(MM_pnl, na.rm = TRUE)
average_Informed_pnl[i, n] <- mean(Informed_pnl, na.rm = TRUE)
average_NoisyInformed_pnl[i, n] <- mean(NoisyInformed_pnl, na.rm = TRUE)
average_Noisy_pnl[i, n] <- mean(Noisy_pnl, na.rm = TRUE)
average_StochNoisy_pnl[i, n] <- mean(StochNoisy_pnl, na.rm = TRUE)
average_mr_pnl[i, n] <- mean(mr_pnl, na.rm = TRUE)
average_mom_pnl[i, n] <- mean(mom_pnl, na.rm = TRUE)
}
}
# Calculate the overall average for each position across all simulations
overall_average_MM_pnl <- rowMeans(average_MM_pnl, na.rm = TRUE)
overall_average_Informed_pnl <- rowMeans(average_Informed_pnl, na.rm = TRUE)
overall_average_NoisyInformed_pnl <- rowMeans(average_NoisyInformed_pnl, na.rm = TRUE)
overall_average_Noisy_pnl <- rowMeans(average_Noisy_pnl, na.rm = TRUE)
overall_average_StochNoisy_pnl <- rowMeans(average_StochNoisy_pnl, na.rm = TRUE)
overall_average_mr_pnl <- rowMeans(average_mr_pnl, na.rm = TRUE)
overall_average_mom_pnl <- rowMeans(average_mom_pnl, na.rm = TRUE)
# Plot the overall averages
plot(overall_average_MM_pnl, type = "l", pch = 16, col = "black", main = "Overall Average PNL", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_MM_pnl, overall_average_Informed_pnl, overall_average_NoisyInformed_pnl, overall_average_Noisy_pnl, overall_average_StochNoisy_pnl, overall_average_mr_pnl, overall_average_mom_pnl)), max(c(overall_average_MM_pnl, overall_average_Informed_pnl, overall_average_NoisyInformed_pnl, overall_average_Noisy_pnl, overall_average_StochNoisy_pnl, overall_average_mr_pnl, overall_average_mom_pnl))))
lines(overall_average_Informed_pnl, type = "l", pch = 16, col = "red")
lines(overall_average_NoisyInformed_pnl, type = "l", pch = 16, col = "green")
lines(overall_average_Noisy_pnl, type = "l", pch = 16, col = "yellow")
lines(overall_average_StochNoisy_pnl, type = "l", pch = 16, col = "blue")
lines(overall_average_mr_pnl, type = "l", pch = 16, col = "purple")
lines(overall_average_mom_pnl, type = "l", pch = 16, col = "orange")
# Add legend
legend("bottomleft", legend = c("Market Maker", "Informed", "Noisy Informed", "Noisy", "Stochastic Noisy", "Mean Reversion", "Momentum"), col = c("black", "red", "green", "yellow", "blue", "purple", "orange"), lty = 1, cex = 0.8)

# Initialize matrices to store averages for each position
average_MM_pos <- matrix(NA, nrow = 100, ncol = 10)
average_Informed_pos <- matrix(NA, nrow = 100, ncol = 10)
average_NoisyInformed_pos <- matrix(NA, nrow = 100, ncol = 10)
average_Noisy_pos <- matrix(NA, nrow = 100, ncol = 10)
average_StochNoisy_pos <- matrix(NA, nrow = 100, ncol = 10)
average_mr_pos <- matrix(NA, nrow = 100, ncol = 10)
average_mom_pos <- matrix(NA, nrow = 100, ncol = 10)
# Loop through each simulation (n)
for (n in 1:10) {
MM_pos_set2 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_2[n, 7])), ", ")
Informed_pos_set2 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_2[n, 9])), ", ")
NoisyInformed_pos_set2 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_2[n, 11])), ", ")
Noisy_pos_set2 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_2[n, 13])), ", ")
StochNoisy_pos_set2 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_2[n, 15])), ", ")
mr_pos_set2 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_2[n, 17])), ", ")
mom_pos_set2 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_2[n, 19])), ", ")
# Loop through each position (i)
for (i in 1:100) {
# Extract True and Expected values for the i-th position
MM_pos <- sapply(MM_pos_set2, function(x) as.numeric(x[i]))
Informed_pos <- sapply(Informed_pos_set2, function(x) as.numeric(x[i]))
NoisyInformed_pos <- sapply(NoisyInformed_pos_set2, function(x) as.numeric(x[i]))
Noisy_pos <- sapply(Noisy_pos_set2, function(x) as.numeric(x[i]))
StochNoisy_pos <- sapply(StochNoisy_pos_set2, function(x) as.numeric(x[i]))
mr_pos <- sapply(mr_pos_set2, function(x) as.numeric(x[i]))
mom_pos <- sapply(mom_pos_set2, function(x) as.numeric(x[i]))
# Calculate the average of True and Expected values for the i-th position
average_MM_pos[i, n] <- mean(MM_pos, na.rm = TRUE)
average_Informed_pos[i, n] <- mean(Informed_pos, na.rm = TRUE)
average_NoisyInformed_pos[i, n] <- mean(NoisyInformed_pos, na.rm = TRUE)
average_Noisy_pos[i, n] <- mean(Noisy_pos, na.rm = TRUE)
average_StochNoisy_pos[i, n] <- mean(StochNoisy_pos, na.rm = TRUE)
average_mr_pos[i, n] <- mean(mr_pos, na.rm = TRUE)
average_mom_pos[i, n] <- mean(mom_pos, na.rm = TRUE)
}
}
# Calculate the overall average for each position across all simulations
overall_average_MM_pos <- rowMeans(average_MM_pos, na.rm = TRUE)
overall_average_Informed_pos <- rowMeans(average_Informed_pos, na.rm = TRUE)
overall_average_NoisyInformed_pos <- rowMeans(average_NoisyInformed_pos, na.rm = TRUE)
overall_average_Noisy_pos <- rowMeans(average_Noisy_pos, na.rm = TRUE)
overall_average_StochNoisy_pos <- rowMeans(average_StochNoisy_pos, na.rm = TRUE)
overall_average_mr_pos <- rowMeans(average_mr_pos, na.rm = TRUE)
overall_average_mom_pos <- rowMeans(average_mom_pos, na.rm = TRUE)
# Plot the overall averages
plot(overall_average_MM_pos, type = "l", pch = 16, col = "black", main = "Overall Average Position", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_MM_pos, overall_average_Informed_pos, overall_average_NoisyInformed_pos, overall_average_Noisy_pos, overall_average_StochNoisy_pos, overall_average_mr_pos, overall_average_mom_pos)), max(c(overall_average_MM_pos, overall_average_Informed_pos, overall_average_NoisyInformed_pos, overall_average_Noisy_pos, overall_average_StochNoisy_pos, overall_average_mr_pos, overall_average_mom_pos))))
lines(overall_average_Informed_pos, type = "l", pch = 16, col = "red")
lines(overall_average_NoisyInformed_pos, type = "l", pch = 16, col = "green")
lines(overall_average_Noisy_pos, type = "l", pch = 16, col = "yellow")
lines(overall_average_StochNoisy_pos, type = "l", pch = 16, col = "blue")
lines(overall_average_mr_pos, type = "l", pch = 16, col = "purple")
lines(overall_average_mom_pos, type = "l", pch = 16, col = "orange")
# Add legend
legend("bottomleft", legend = c("Market Maker", "Informed", "Noisy Informed", "Noisy", "Stochastic Noisy", "Mean Reversion", "Momentum"), col = c("black", "red", "green", "yellow", "blue", "purple", "orange"), lty = 1, cex = 0.8)

set 3 (2 stochastic noisy + 2 mr + 2 mom)
# Initialize matrices to store averages for each position
average_true <- matrix(NA, nrow = 100, ncol = 10)
average_expected <- matrix(NA, nrow = 100, ncol = 10)
# Loop through each simulation (n)
for (n in 1:10) {
# Extract True values from the aggregated_results_4 dataframe
TrueValues_set3 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_3[n, 2])), ", ")
# Extract Expected values from the aggregated_results_4 dataframe
ExpectedValues_set3 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_3[n, 3])), ", ")
# Loop through each position (i)
for (i in 1:100) {
# Extract True and Expected values for the i-th position
True_values <- sapply(TrueValues_set3, function(x) as.numeric(x[i]))
Expected_values <- sapply(ExpectedValues_set3, function(x) as.numeric(x[i]))
# Calculate the average of True and Expected values for the i-th position
average_true[i, n] <- mean(True_values, na.rm = TRUE)
average_expected[i, n] <- mean(Expected_values, na.rm = TRUE)
}
}
# Calculate the overall average for each position across all simulations
overall_average_true <- rowMeans(average_true, na.rm = TRUE)
overall_average_expected <- rowMeans(average_expected, na.rm = TRUE)
# Plot the overall averages
plot(overall_average_true, type = "l", pch = 16, col = "blue", main = "Overall Average of True vs Expected Values", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_true, overall_average_expected)), max(c(overall_average_true, overall_average_expected))))
lines(overall_average_expected, type = "l", pch = 16, col = "red")
legend("topright", legend = c("True Values", "Expected Values"), col = c("blue", "red"), lty = 1, cex = 0.8)

# Initialize matrices to store averages for each position
average_bid <- matrix(NA, nrow = 100, ncol = 10)
average_ask <- matrix(NA, nrow = 100, ncol = 10)
# Loop through each simulation (n)
for (n in 1:10) {
# Extract True values from the aggregated_results_4 dataframe
Bids_set3 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_3[n, 4])), ", ")
# Extract Expected values from the aggregated_results_4 dataframe
Asks_set3 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_3[n, 5])), ", ")
# Loop through each position (i)
for (i in 1:100) {
# Extract True and Expected values for the i-th position
Bids <- sapply(Bids_set3, function(x) as.numeric(x[i]))
Asks <- sapply(Asks_set3, function(x) as.numeric(x[i]))
# Calculate the average of True and Expected values for the i-th position
average_bid[i, n] <- mean(Bids, na.rm = TRUE)
average_ask[i, n] <- mean(Asks, na.rm = TRUE)
}
}
# Calculate the overall average for each position across all simulations
overall_average_bid <- rowMeans(average_bid, na.rm = TRUE)
overall_average_ask <- rowMeans(average_ask, na.rm = TRUE)
# Plot the overall averages
plot(overall_average_bid, type = "l", pch = 16, col = "blue", main = "Overall Average of Bids vs Asks", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_bid, overall_average_ask)), max(c(overall_average_bid, overall_average_ask))))
lines(overall_average_ask, type = "l", pch = 16, col = "red")
legend("topright", legend = c("Bids", "Asks"), col = c("blue", "red"), lty = 1, cex = 0.8)

# Initialize matrices to store averages for each position
average_bid <- matrix(NA, nrow = 100, ncol = 10)
average_ask <- matrix(NA, nrow = 100, ncol = 10)
# Loop through each simulation (n)
for (n in 1:10) {
# Extract True values from the aggregated_results_4 dataframe
Bids_set3 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_3[n, 4])), ", ")
# Extract Expected values from the aggregated_results_4 dataframe
Asks_set3 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_3[n, 5])), ", ")
# Loop through each position (i)
for (i in 1:100) {
# Extract True and Expected values for the i-th position
Bids <- sapply(Bids_set3, function(x) as.numeric(x[i]))
Asks <- sapply(Asks_set3, function(x) as.numeric(x[i]))
# Calculate the average of True and Expected values for the i-th position
average_bid[i, n] <- mean(Bids, na.rm = TRUE)
average_ask[i, n] <- mean(Asks, na.rm = TRUE)
}
}
# Calculate the overall average for each position across all simulations
overall_average_bid <- rowMeans(average_bid, na.rm = TRUE)
overall_average_ask <- rowMeans(average_ask, na.rm = TRUE)
## True Value
# Initialize matrices to store averages for each position
average_true <- matrix(NA, nrow = 100, ncol = 10)
average_expected <- matrix(NA, nrow = 100, ncol = 10)
# Loop through each simulation (n)
for (n in 1:10) {
# Extract True values from the aggregated_results_4 dataframe
TrueValues_set3 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_3[n, 2])), ", ")
# Extract Expected values from the aggregated_results_4 dataframe
ExpectedValues_set3 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_3[n, 3])), ", ")
# Loop through each position (i)
for (i in 1:100) {
# Extract True and Expected values for the i-th position
True_values <- sapply(TrueValues_set3, function(x) as.numeric(x[i]))
Expected_values <- sapply(ExpectedValues_set3, function(x) as.numeric(x[i]))
# Calculate the average of True and Expected values for the i-th position
average_true[i, n] <- mean(True_values, na.rm = TRUE)
average_expected[i, n] <- mean(Expected_values, na.rm = TRUE)
}
}
# Calculate the overall average for each position across all simulations
overall_average_true <- rowMeans(average_true, na.rm = TRUE)
overall_average_expected <- rowMeans(average_expected, na.rm = TRUE)
# Plot the overall averages
#plot(overall_average_true, type = "l", pch = 16, col = "blue", main = "Overall Average of True vs Expected Values", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_true, overall_average_expected)), max(c(overall_average_true, overall_average_expected))))
#lines(overall_average_expected, type = "l", pch = 16, col = "red")
#legend("topright", legend = c("True Values", "Expected Values"), col = c("blue", "red"), lty = 1, cex = 0.8)
# Plot the overall averages
plot(overall_average_bid, type = "l", pch = 16, col = "blue", main = "Overall Average of Bids vs Asks & True vs Expected Values", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_bid, overall_average_ask, overall_average_true, overall_average_expected)), max(c(overall_average_bid, overall_average_ask, overall_average_true, overall_average_expected))))
lines(overall_average_ask, type = "l", pch = 16, col = "red")
lines(overall_average_true, type = "l", pch = 16, col = "green")
lines(overall_average_expected, type = "l", pch = 16, col = "purple")
legend("bottomleft", legend = c("Bids", "Asks", "True Value", "Expected Value"), col = c("blue", "red", "green", "purple"), lty = 1, cex = 0.8)

# Initialize matrices to store averages for each position
average_MM_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_StochNoisy1_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_StochNoisy2_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_mr1_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_mr2_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_mom1_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_mom2_pnl <- matrix(NA, nrow = 100, ncol = 10)
# Loop through each simulation (n)
for (n in 1:10) {
MM_pnl_set3 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_3[n, 6])), ", ")
StochNoisy1_pnl_set3 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_3[n, 8])), ", ")
StochNoisy2_pnl_set3 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_3[n, 10])), ", ")
mr1_pnl_set3 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_3[n, 12])), ", ")
mr2_pnl_set3 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_3[n, 14])), ", ")
mom1_pnl_set3 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_3[n, 16])), ", ")
mom2_pnl_set3 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_3[n, 18])), ", ")
# Loop through each position (i)
for (i in 1:100) {
# Extract True and Expected values for the i-th position
MM_pnl <- sapply(MM_pnl_set3, function(x) as.numeric(x[i]))
StochNoisy1_pnl <- sapply(StochNoisy1_pnl_set3, function(x) as.numeric(x[i]))
StochNoisy2_pnl <- sapply(StochNoisy2_pnl_set3, function(x) as.numeric(x[i]))
mr1_pnl <- sapply(mr1_pnl_set3, function(x) as.numeric(x[i]))
mr2_pnl <- sapply(mr2_pnl_set3, function(x) as.numeric(x[i]))
mom1_pnl <- sapply(mom1_pnl_set3, function(x) as.numeric(x[i]))
mom2_pnl <- sapply(mom2_pnl_set3, function(x) as.numeric(x[i]))
# Calculate the average of True and Expected values for the i-th position
average_MM_pnl[i, n] <- mean(MM_pnl, na.rm = TRUE)
average_StochNoisy1_pnl[i, n] <- mean(StochNoisy1_pnl, na.rm = TRUE)
average_StochNoisy2_pnl[i, n] <- mean(StochNoisy2_pnl, na.rm = TRUE)
average_mr1_pnl[i, n] <- mean(mr1_pnl, na.rm = TRUE)
average_mr2_pnl[i, n] <- mean(mr2_pnl, na.rm = TRUE)
average_mom1_pnl[i, n] <- mean(mom1_pnl, na.rm = TRUE)
average_mom2_pnl[i, n] <- mean(mom2_pnl, na.rm = TRUE)
}
}
# Calculate the overall average for each position across all simulations
overall_average_MM_pnl <- rowMeans(average_MM_pnl, na.rm = TRUE)
overall_average_StochNoisy1_pnl <- rowMeans(average_StochNoisy1_pnl, na.rm = TRUE)
overall_average_StochNoisy2_pnl <- rowMeans(average_StochNoisy2_pnl, na.rm = TRUE)
overall_average_mr1_pnl <- rowMeans(average_mr1_pnl, na.rm = TRUE)
overall_average_mr2_pnl <- rowMeans(average_mr2_pnl, na.rm = TRUE)
overall_average_mom1_pnl <- rowMeans(average_mom1_pnl, na.rm = TRUE)
overall_average_mom2_pnl <- rowMeans(average_mom2_pnl, na.rm = TRUE)
# Plot the overall averages
plot(overall_average_MM_pnl, type = "l", pch = 16, col = "black", main = "Overall Average PNL", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_MM_pnl, overall_average_StochNoisy1_pnl, overall_average_StochNoisy2_pnl, overall_average_mr1_pnl, overall_average_mr2_pnl, overall_average_mom1_pnl, overall_average_mom2_pnl)), max(c(overall_average_MM_pnl, overall_average_StochNoisy1_pnl, overall_average_StochNoisy2_pnl, overall_average_mr1_pnl, overall_average_mr2_pnl, overall_average_mom1_pnl, overall_average_mom2_pnl))))
lines(overall_average_StochNoisy1_pnl, type = "l", pch = 16, col = "red")
lines(overall_average_StochNoisy2_pnl, type = "l", pch = 16, col = "green")
lines(overall_average_mr1_pnl, type = "l", pch = 16, col = "yellow")
lines(overall_average_mr2_pnl, type = "l", pch = 16, col = "blue")
lines(overall_average_mom1_pnl, type = "l", pch = 16, col = "purple")
lines(overall_average_mom2_pnl, type = "l", pch = 16, col = "orange")
# Add legend
legend("bottomleft", legend = c("Market Maker", "Stochastic Noisy 1", "Stochastic Noisy 2", "Mean Reversion 1", "Mean Reversion 2", "Momentum 1", "Momentum 2"), col = c("black", "red", "green", "yellow", "blue", "purple", "orange"), lty = 1, cex = 0.8)

# Initialize matrices to store averages for each position
average_MM_pos <- matrix(NA, nrow = 100, ncol = 10)
average_StochNoisy1_pos <- matrix(NA, nrow = 100, ncol = 10)
average_StochNoisy2_pos <- matrix(NA, nrow = 100, ncol = 10)
average_mr1_pos <- matrix(NA, nrow = 100, ncol = 10)
average_mr2_pos <- matrix(NA, nrow = 100, ncol = 10)
average_mom1_pos <- matrix(NA, nrow = 100, ncol = 10)
average_mom2_pos <- matrix(NA, nrow = 100, ncol = 10)
# Loop through each simulation (n)
for (n in 1:10) {
MM_pos_set3 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_3[n, 7])), ", ")
StochNoisy1_pos_set3 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_3[n, 9])), ", ")
StochNoisy2_pos_set3 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_3[n, 11])), ", ")
mr1_pos_set3 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_3[n, 12])), ", ")
mr2_pos_set3 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_3[n, 15])), ", ")
mom1_pos_set3 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_3[n, 17])), ", ")
mom2_pos_set3 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_3[n, 19])), ", ")
# Loop through each position (i)
for (i in 1:100) {
# Extract True and Expected values for the i-th position
MM_pos <- sapply(MM_pos_set3, function(x) as.numeric(x[i]))
StochNoisy1_pos <- sapply(StochNoisy1_pos_set3, function(x) as.numeric(x[i]))
StochNoisy2_pos <- sapply(StochNoisy2_pos_set3, function(x) as.numeric(x[i]))
mr1_pos <- sapply(mr1_pos_set3, function(x) as.numeric(x[i]))
mr2_pos <- sapply(mr2_pos_set3, function(x) as.numeric(x[i]))
mom1_pos <- sapply(mom1_pos_set3, function(x) as.numeric(x[i]))
mom2_pos <- sapply(mom2_pos_set3, function(x) as.numeric(x[i]))
# Calculate the average of True and Expected values for the i-th position
average_MM_pos[i, n] <- mean(MM_pos, na.rm = TRUE)
average_StochNoisy1_pos[i, n] <- mean(StochNoisy1_pos, na.rm = TRUE)
average_StochNoisy2_pos[i, n] <- mean(StochNoisy2_pos, na.rm = TRUE)
average_mr1_pos[i, n] <- mean(mr1_pos, na.rm = TRUE)
average_mr2_pos[i, n] <- mean(mr2_pos, na.rm = TRUE)
average_mom1_pos[i, n] <- mean(mom1_pos, na.rm = TRUE)
average_mom2_pos[i, n] <- mean(mom2_pos, na.rm = TRUE)
}
}
# Calculate the overall average for each position across all simulations
overall_average_MM_pos <- rowMeans(average_MM_pos, na.rm = TRUE)
overall_average_StochNoisy1_pos <- rowMeans(average_StochNoisy1_pos, na.rm = TRUE)
overall_average_StochNoisy2_pos <- rowMeans(average_StochNoisy2_pos, na.rm = TRUE)
overall_average_mr1_pos <- rowMeans(average_mr1_pos, na.rm = TRUE)
overall_average_mr2_pos <- rowMeans(average_mr2_pos, na.rm = TRUE)
overall_average_mom1_pos <- rowMeans(average_mom1_pos, na.rm = TRUE)
overall_average_mom2_pos <- rowMeans(average_mom2_pos, na.rm = TRUE)
# Plot the overall averages
plot(overall_average_MM_pos, type = "l", pch = 16, col = "black", main = "Overall Average Position", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_MM_pos, overall_average_StochNoisy1_pos, overall_average_StochNoisy2_pos, overall_average_mr1_pos, overall_average_mr2_pos, overall_average_mom1_pos, overall_average_mom2_pos)), max(c(overall_average_MM_pos, overall_average_StochNoisy1_pos, overall_average_StochNoisy2_pos, overall_average_mr1_pos, overall_average_mr2_pos, overall_average_mom1_pos, overall_average_mom2_pos))))
lines(overall_average_StochNoisy1_pos, type = "l", pch = 16, col = "red")
lines(overall_average_StochNoisy2_pos, type = "l", pch = 16, col = "green")
lines(overall_average_mr1_pos, type = "l", pch = 16, col = "yellow")
lines(overall_average_mr2_pos, type = "l", pch = 16, col = "blue")
lines(overall_average_mom1_pos, type = "l", pch = 16, col = "purple")
lines(overall_average_mom2_pos, type = "l", pch = 16, col = "orange")
# Add legend
legend("topleft", legend = c("Market Maker", "Stochastic Noisy 1", "Stochastic Noisy 2", "Mean Reversion 1", "Mean Reversion 2", "Momentum 1", "Momentum 2"), col = c("black", "red", "green", "yellow", "blue", "purple", "orange"), lty = 1, cex = 0.8)

set 4 (1 informed + 2 noisy informed + 2 noisy + 1 stochastic
noisy)
# Initialize empty vectors to store true and expected values
TrueValues_set4 <- numeric()
ExpectedValues_set4 <- numeric()
# Loop through each iteration (n)
for (n in 1:10) {
# Extract True values from the aggregated_results_1 dataframe
TrueValue_set4 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_4[n, 2])), ", ")[[1]]
# Extract Expected values from the aggregated_results_1 dataframe
ExpectedValue_set4 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_4[n, 3])), ", ")[[1]]
# Append the True and Expected values to their respective vectors
TrueValues_set4 <- c(TrueValues_set4, as.numeric(TrueValue_set4))
ExpectedValues_set4 <- c(ExpectedValues_set4, as.numeric(ExpectedValue_set4))
}
# Calculate the average of True values
average_true <- mean(TrueValues_set4)
# Calculate the average of Expected values
average_expected <- mean(ExpectedValues_set4)
# Plot True and Expected values on the same plot
plot(TrueValues_set4, type = "l", pch = 16, col = "blue", main = "True vs Expected Values in set 4", xlab = "Iteration", ylab = "Value")
lines(ExpectedValues_set4, type = "l", pch = 16, col = "red")
# Add legend
legend("topright", legend = c("True Values", "Expected Values"), col = c("blue", "red"), lty = 1, cex = 0.8)
# Add horizontal lines for the averages
abline(h = average_true, col = "blue", lwd = 1)
abline(h = average_expected, col = "red", lwd = 1)

# Initialize matrices to store averages for each position
average_true <- matrix(NA, nrow = 100, ncol = 10)
average_expected <- matrix(NA, nrow = 100, ncol = 10)
# Loop through each simulation (n)
for (n in 1:10) {
# Extract True values from the aggregated_results_4 dataframe
TrueValues_set4 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_4[n, 2])), ", ")
# Extract Expected values from the aggregated_results_4 dataframe
ExpectedValues_set4 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_4[n, 3])), ", ")
# Loop through each position (i)
for (i in 1:100) {
# Extract True and Expected values for the i-th position
True_values <- sapply(TrueValues_set4, function(x) as.numeric(x[i]))
Expected_values <- sapply(ExpectedValues_set4, function(x) as.numeric(x[i]))
# Calculate the average of True and Expected values for the i-th position
average_true[i, n] <- mean(True_values, na.rm = TRUE)
average_expected[i, n] <- mean(Expected_values, na.rm = TRUE)
}
}
# Calculate the overall average for each position across all simulations
overall_average_true <- rowMeans(average_true, na.rm = TRUE)
overall_average_expected <- rowMeans(average_expected, na.rm = TRUE)
# Plot the overall averages
plot(overall_average_true, type = "l", pch = 16, col = "blue", main = "Overall Average of True vs Expected Values", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_true, overall_average_expected)), max(c(overall_average_true, overall_average_expected))))
lines(overall_average_expected, type = "l", pch = 16, col = "red")
legend("topright", legend = c("True Values", "Expected Values"), col = c("blue", "red"), lty = 1, cex = 0.8)

# Initialize empty vectors to store the Bid and Ask values
Bids_set4 <- numeric()
Asks_set4 <- numeric()
# Loop through each iteration (n)
for (n in 1:10) {
# Extract Bid values from the aggregated_results_1 dataframe
Bid_set4 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_4[n, 4])), ", ")[[1]]
# Extract Ask values from the aggregated_results_1 dataframe (next column)
Ask_set4 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_4[n, 5])), ", ")[[1]]
# Append the Bid and Ask values to their respective vectors
Bids_set4 <- c(Bids_set4, as.numeric(Bid_set4))
Asks_set4 <- c(Asks_set4, as.numeric(Ask_set4))
}
# Calculate the average of Bid and Ask values
average_bids <- mean(Bids_set4, na.rm = TRUE)
average_asks <- mean(Asks_set4, na.rm = TRUE)
# Plot the Bid and Ask values on the same plot
plot(Bids_set4, type = "l", pch = 16, col = "blue", main = "Bids vs Asks in set 4", xlab = "Iteration", ylab = "Value", ylim = c(min(c(Bids_set4, Asks_set4)), max(c(Bids_set4, Asks_set4))))
lines(Asks_set4, type = "l", pch = 16, col = "red")
# Add legend
legend("topright", legend = c("Bids", "Asks"), col = c("blue", "red"), lty = 1, cex = 0.8)
# Add horizontal lines for the averages
abline(h = average_bids, col = "blue", lty = 1)
abline(h = average_asks, col = "red", lty = 1)

# Initialize matrices to store averages for each position
average_bid <- matrix(NA, nrow = 100, ncol = 10)
average_ask <- matrix(NA, nrow = 100, ncol = 10)
# Loop through each simulation (n)
for (n in 1:10) {
# Extract True values from the aggregated_results_4 dataframe
Bids_set4 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_4[n, 4])), ", ")
# Extract Expected values from the aggregated_results_4 dataframe
Asks_set4 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_4[n, 5])), ", ")
# Loop through each position (i)
for (i in 1:100) {
# Extract True and Expected values for the i-th position
Bids <- sapply(Bids_set4, function(x) as.numeric(x[i]))
Asks <- sapply(Asks_set4, function(x) as.numeric(x[i]))
# Calculate the average of True and Expected values for the i-th position
average_bid[i, n] <- mean(Bids, na.rm = TRUE)
average_ask[i, n] <- mean(Asks, na.rm = TRUE)
}
}
# Calculate the overall average for each position across all simulations
overall_average_bid <- rowMeans(average_bid, na.rm = TRUE)
overall_average_ask <- rowMeans(average_ask, na.rm = TRUE)
# Plot the overall averages
plot(overall_average_bid, type = "l", pch = 16, col = "blue", main = "Overall Average of Bids vs Asks", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_bid, overall_average_ask)), max(c(overall_average_bid, overall_average_ask))))
lines(overall_average_ask, type = "l", pch = 16, col = "red")
legend("topright", legend = c("Bids", "Asks"), col = c("blue", "red"), lty = 1, cex = 0.8)

# Initialize matrices to store averages for each position
average_bid <- matrix(NA, nrow = 100, ncol = 10)
average_ask <- matrix(NA, nrow = 100, ncol = 10)
# Loop through each simulation (n)
for (n in 1:10) {
# Extract True values from the aggregated_results_4 dataframe
Bids_set4 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_4[n, 4])), ", ")
# Extract Expected values from the aggregated_results_4 dataframe
Asks_set4 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_4[n, 5])), ", ")
# Loop through each position (i)
for (i in 1:100) {
# Extract True and Expected values for the i-th position
Bids <- sapply(Bids_set4, function(x) as.numeric(x[i]))
Asks <- sapply(Asks_set4, function(x) as.numeric(x[i]))
# Calculate the average of True and Expected values for the i-th position
average_bid[i, n] <- mean(Bids, na.rm = TRUE)
average_ask[i, n] <- mean(Asks, na.rm = TRUE)
}
}
# Calculate the overall average for each position across all simulations
overall_average_bid <- rowMeans(average_bid, na.rm = TRUE)
overall_average_ask <- rowMeans(average_ask, na.rm = TRUE)
## True Value
# Initialize matrices to store averages for each position
average_true <- matrix(NA, nrow = 100, ncol = 10)
average_expected <- matrix(NA, nrow = 100, ncol = 10)
# Loop through each simulation (n)
for (n in 1:10) {
# Extract True values from the aggregated_results_4 dataframe
TrueValues_set4 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_4[n, 2])), ", ")
# Extract Expected values from the aggregated_results_4 dataframe
ExpectedValues_set4 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_4[n, 3])), ", ")
# Loop through each position (i)
for (i in 1:100) {
# Extract True and Expected values for the i-th position
True_values <- sapply(TrueValues_set4, function(x) as.numeric(x[i]))
Expected_values <- sapply(ExpectedValues_set4, function(x) as.numeric(x[i]))
# Calculate the average of True and Expected values for the i-th position
average_true[i, n] <- mean(True_values, na.rm = TRUE)
average_expected[i, n] <- mean(Expected_values, na.rm = TRUE)
}
}
# Calculate the overall average for each position across all simulations
overall_average_true <- rowMeans(average_true, na.rm = TRUE)
overall_average_expected <- rowMeans(average_expected, na.rm = TRUE)
# Plot the overall averages
#plot(overall_average_true, type = "l", pch = 16, col = "blue", main = "Overall Average of True vs Expected Values", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_true, overall_average_expected)), max(c(overall_average_true, overall_average_expected))))
#lines(overall_average_expected, type = "l", pch = 16, col = "red")
#legend("topright", legend = c("True Values", "Expected Values"), col = c("blue", "red"), lty = 1, cex = 0.8)
# Plot the overall averages
plot(overall_average_bid, type = "l", pch = 16, col = "blue", main = "Overall Average of Bids vs Asks & True vs Expected Values", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_bid, overall_average_ask, overall_average_true, overall_average_expected)), max(c(overall_average_bid, overall_average_ask, overall_average_true, overall_average_expected))))
lines(overall_average_ask, type = "l", pch = 16, col = "red")
lines(overall_average_true, type = "l", pch = 16, col = "green")
lines(overall_average_expected, type = "l", pch = 16, col = "purple")
legend("bottomleft", legend = c("Bids", "Asks", "True Value", "Expected Value"), col = c("blue", "red", "green", "purple"), lty = 1, cex = 0.8)

# Initialize empty vectors to store the Bid and Ask values
MM_pnl_set4 <- numeric()
Informed_pnl_set4 <- numeric()
NoisyInformed1_pnl_set4 <- numeric()
NoisyInformed2_pnl_set4 <- numeric()
Noisy1_pnl_set4 <- numeric()
Noisy2_pnl_set4 <- numeric()
StochNoisy_pnl_set4 <- numeric()
# Loop through each iteration (n)
for (n in 1:10) {
MM_pnl_values <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_4[n, 6])), ", ")[[1]]
Informed_pnl_values <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_4[n, 8])), ", ")[[1]]
NoisyInformed1_pnl_values <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_4[n, 10])), ", ")[[1]]
NoisyInformed2_pnl_values <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_4[n, 12])), ", ")[[1]]
Noisy1_pnl_values <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_4[n, 14])), ", ")[[1]]
Noisy2_pnl_values <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_4[n, 16])), ", ")[[1]]
StochNoisy_pnl_values <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_4[n, 18])), ", ")[[1]]
# Convert Bid and Ask values to numeric and append to the vectors
MM_pnl_set4 <- c(MM_pnl_set4, as.numeric(MM_pnl_values))
Informed_pnl_set4 <- c(Informed_pnl_set4, as.numeric(Informed_pnl_values))
NoisyInformed1_pnl_set4 <- c(NoisyInformed1_pnl_set4, as.numeric(NoisyInformed1_pnl_values))
NoisyInformed2_pnl_set4 <- c(NoisyInformed2_pnl_set4, as.numeric(NoisyInformed2_pnl_values))
Noisy1_pnl_set4 <- c(Noisy_pnl_set4, as.numeric(Noisy1_pnl_values))
Noisy2_pnl_set4 <- c(Noisy2_pnl_set4, as.numeric(Noisy2_pnl_values))
StochNoisy_pnl_set4 <- c(StochNoisy_pnl_set4, as.numeric(StochNoisy_pnl_values))
}
# Calculate the average of Bid and Ask values
#average_MM <- mean(MM_set4, na.rm = TRUE)
#average_IN <- mean(IN_set4, na.rm = TRUE)
# Plot the Bid and Ask values on the same plot
plot(MM_pnl_set4, type = "l", pch = 16, col = "black", main = "PNL in set 4", xlab = "Iteration", ylab = "Value", ylim = c(min(c(MM_pnl_set4, Informed_pnl_set4, NoisyInformed1_pnl_set4, NoisyInformed2_pnl_set4, Noisy1_pnl_set4, Noisy2_pnl_set4, StochNoisy_pnl_set4)), max(c(MM_pnl_set4, Informed_pnl_set4, NoisyInformed1_pnl_set4, NoisyInformed2_pnl_set4, Noisy1_pnl_set4, Noisy2_pnl_set4, StochNoisy_pnl_set4))))
lines(Informed_pnl_set4, type = "l", pch = 16, col = "red")
lines(NoisyInformed1_pnl_set4, type = "l", pch = 16, col = "green")
lines(NoisyInformed2_pnl_set4, type = "l", pch = 16, col = "yellow")
lines(Noisy1_pnl_set4, type = "l", pch = 16, col = "blue")
lines(Noisy2_pnl_set4, type = "l", pch = 16, col = "purple")
lines(StochNoisy_pnl_set4, type = "l", pch = 16, col = "orange")
# Add legend
legend("bottomright", legend = c("Market Maker", "Informed", "Noisy Informed 1", "Noisy Informed 2", "Noisy 1", "Noisy 2", "Stochastic Noisy"), col = c("black", "red", "green", "yellow", "blue", "purple", "orange"), lty = 1, cex = 0.8)

# Add horizontal lines for the averages
#abline(h = average_MM, col = "blue", lty = 1)
#abline(h = average_IN, col = "red", lty = 1)
# Initialize matrices to store averages for each position
average_MM_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_Informed_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_NoisyInformed1_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_NoisyInformed2_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_Noisy1_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_Noisy2_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_StochNoisy_pnl <- matrix(NA, nrow = 100, ncol = 10)
# Loop through each simulation (n)
for (n in 1:10) {
MM_pnl_set4 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_4[n, 6])), ", ")
Informed_pnl_set4 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_4[n, 8])), ", ")
NoisyInformed1_pnl_set4 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_4[n, 10])), ", ")
NoisyInformed2_pnl_set4 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_4[n, 12])), ", ")
Noisy1_pnl_set4 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_4[n, 14])), ", ")
Noisy2_pnl_set4 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_4[n, 16])), ", ")
StochNoisy_pnl_set4 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_4[n, 18])), ", ")
# Loop through each position (i)
for (i in 1:100) {
# Extract True and Expected values for the i-th position
MM_pnl <- sapply(MM_pnl_set4, function(x) as.numeric(x[i]))
Informed_pnl <- sapply(Informed_pnl_set4, function(x) as.numeric(x[i]))
NoisyInformed1_pnl <- sapply(NoisyInformed1_pnl_set4, function(x) as.numeric(x[i]))
NoisyInformed2_pnl <- sapply(NoisyInformed2_pnl_set4, function(x) as.numeric(x[i]))
Noisy1_pnl <- sapply(Noisy1_pnl_set4, function(x) as.numeric(x[i]))
Noisy2_pnl <- sapply(Noisy2_pnl_set4, function(x) as.numeric(x[i]))
StochNoisy_pnl <- sapply(StochNoisy_pnl_set4, function(x) as.numeric(x[i]))
# Calculate the average of True and Expected values for the i-th position
average_MM_pnl[i, n] <- mean(MM_pnl, na.rm = TRUE)
average_Informed_pnl[i, n] <- mean(Informed_pnl, na.rm = TRUE)
average_NoisyInformed1_pnl[i, n] <- mean(NoisyInformed1_pnl, na.rm = TRUE)
average_NoisyInformed2_pnl[i, n] <- mean(NoisyInformed2_pnl, na.rm = TRUE)
average_Noisy1_pnl[i, n] <- mean(Noisy1_pnl, na.rm = TRUE)
average_Noisy2_pnl[i, n] <- mean(Noisy2_pnl, na.rm = TRUE)
average_StochNoisy_pnl[i, n] <- mean(StochNoisy_pnl, na.rm = TRUE)
}
}
# Calculate the overall average for each position across all simulations
overall_average_MM_pnl <- rowMeans(average_MM_pnl, na.rm = TRUE)
overall_average_Informed_pnl <- rowMeans(average_Informed_pnl, na.rm = TRUE)
overall_average_NoisyInformed1_pnl <- rowMeans(average_NoisyInformed1_pnl, na.rm = TRUE)
overall_average_NoisyInformed2_pnl <- rowMeans(average_NoisyInformed2_pnl, na.rm = TRUE)
overall_average_Noisy1_pnl <- rowMeans(average_Noisy1_pnl, na.rm = TRUE)
overall_average_Noisy2_pnl <- rowMeans(average_Noisy2_pnl, na.rm = TRUE)
overall_average_StochNoisy_pnl <- rowMeans(average_StochNoisy_pnl, na.rm = TRUE)
# Plot the overall averages
plot(overall_average_MM_pnl, type = "l", pch = 16, col = "black", main = "Overall Average PNL", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_MM_pnl, overall_average_Informed_pnl, overall_average_NoisyInformed1_pnl, overall_average_NoisyInformed2_pnl, overall_average_Noisy1_pnl, overall_average_Noisy2_pnl, overall_average_StochNoisy_pnl)), max(c(overall_average_MM_pnl, overall_average_Informed_pnl, overall_average_NoisyInformed1_pnl, overall_average_NoisyInformed2_pnl, overall_average_Noisy1_pnl, overall_average_Noisy2_pnl, overall_average_StochNoisy_pnl))))
lines(overall_average_Informed_pnl, type = "l", pch = 16, col = "red")
lines(overall_average_NoisyInformed1_pnl, type = "l", pch = 16, col = "green")
lines(overall_average_NoisyInformed2_pnl, type = "l", pch = 16, col = "yellow")
lines(overall_average_Noisy1_pnl, type = "l", pch = 16, col = "blue")
lines(overall_average_Noisy2_pnl, type = "l", pch = 16, col = "purple")
lines(overall_average_StochNoisy_pnl, type = "l", pch = 16, col = "orange")
# Add legend
legend("bottomleft", legend = c("Market Maker", "Informed", "Noisy Informed 1", "Noisy Informed 2", "Noisy 1", "Noisy 2", "Stochastic Noisy"), col = c("black", "red", "green", "yellow", "blue", "purple", "orange"), lty = 1, cex = 0.8)

# Initialize empty vectors to store the Bid and Ask values
MM_pos_set4 <- numeric()
Informed_pos_set4 <- numeric()
NoisyInformed1_pos_set4 <- numeric()
NoisyInformed2_pos_set4 <- numeric()
Noisy1_pos_set4 <- numeric()
Noisy2_pos_set4 <- numeric()
StochNoisy_pos_set4 <- numeric()
# Loop through each iteration (n)
for (n in 1:10) {
MM_pos_values <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_4[n, 7])), ", ")[[1]]
Informed_pos_values <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_4[n, 9])), ", ")[[1]]
NoisyInformed1_pos_values <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_4[n, 11])), ", ")[[1]]
NoisyInformed2_pos_values <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_4[n, 13])), ", ")[[1]]
Noisy1_pos_values <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_4[n, 15])), ", ")[[1]]
Noisy2_pos_values <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_4[n, 17])), ", ")[[1]]
StochNoisy_pos_values <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_4[n, 19])), ", ")[[1]]
# Convert Bid and Ask values to numeric and append to the vectors
MM_pos_set4 <- c(MM_pos_set4, as.numeric(MM_pos_values))
Informed_pos_set4 <- c(Informed_pos_set4, as.numeric(Informed_pos_values))
NoisyInformed1_pos_set4 <- c(NoisyInformed1_pos_set4, as.numeric(NoisyInformed1_pos_values))
NoisyInformed2_pos_set4 <- c(NoisyInformed2_pos_set4, as.numeric(NoisyInformed2_pos_values))
Noisy1_pos_set4 <- c(Noisy_pos_set4, as.numeric(Noisy1_pos_values))
Noisy2_pos_set4 <- c(Noisy2_pos_set4, as.numeric(Noisy2_pos_values))
StochNoisy_pos_set4 <- c(StochNoisy_pos_set4, as.numeric(StochNoisy_pos_values))
}
# Calculate the average of Bid and Ask values
#average_MM <- mean(MM_set4, na.rm = TRUE)
#average_IN <- mean(IN_set4, na.rm = TRUE)
# Plot the Bid and Ask values on the same plot
plot(MM_pos_set4, type = "l", pch = 16, col = "black", main = "Position in set 4", xlab = "Iteration", ylab = "Value", ylim = c(min(c(MM_pos_set4, Informed_pos_set4, NoisyInformed1_pos_set4, NoisyInformed2_pos_set4, Noisy1_pos_set4, Noisy2_pos_set4, StochNoisy_pos_set4)), max(c(MM_pos_set4, Informed_pos_set4, NoisyInformed1_pos_set4, NoisyInformed2_pos_set4, Noisy1_pos_set4, Noisy2_pos_set4, StochNoisy_pos_set4))))
lines(Informed_pos_set4, type = "l", pch = 16, col = "red")
lines(NoisyInformed1_pos_set4, type = "l", pch = 16, col = "green")
lines(NoisyInformed2_pos_set4, type = "l", pch = 16, col = "yellow")
lines(Noisy1_pos_set4, type = "l", pch = 16, col = "blue")
lines(Noisy2_pos_set4, type = "l", pch = 16, col = "purple")
lines(StochNoisy_pos_set4, type = "l", pch = 16, col = "orange")
# Add legend
legend("topleft", legend = c("Market Maker", "Informed", "Noisy Informed 1", "Noisy Informed 2", "Noisy 1", "Noisy 2", "Stochastic Noisy"), col = c("black", "red", "green", "yellow", "blue", "purple", "orange"), lty = 1, cex = 0.8)

# Add horizontal lines for the averages
#abline(h = average_MM, col = "blue", lty = 1)
#abline(h = average_IN, col = "red", lty = 1)
# Initialize matrices to store averages for each position
average_MM_pos <- matrix(NA, nrow = 100, ncol = 10)
average_Informed_pos <- matrix(NA, nrow = 100, ncol = 10)
average_NoisyInformed1_pos <- matrix(NA, nrow = 100, ncol = 10)
average_NoisyInformed2_pos <- matrix(NA, nrow = 100, ncol = 10)
average_Noisy1_pos <- matrix(NA, nrow = 100, ncol = 10)
average_Noisy2_pos <- matrix(NA, nrow = 100, ncol = 10)
average_StochNoisy_pos <- matrix(NA, nrow = 100, ncol = 10)
# Loop through each simulation (n)
for (n in 1:10) {
MM_pos_set4 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_4[n, 7])), ", ")
Informed_pos_set4 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_4[n, 9])), ", ")
NoisyInformed1_pos_set4 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_4[n, 11])), ", ")
NoisyInformed2_pos_set4 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_4[n, 13])), ", ")
Noisy1_pos_set4 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_4[n, 15])), ", ")
Noisy2_pos_set4 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_4[n, 17])), ", ")
StochNoisy_pos_set4 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_4[n, 19])), ", ")
# Loop through each position (i)
for (i in 1:100) {
# Extract True and Expected values for the i-th position
MM_pos <- sapply(MM_pos_set4, function(x) as.numeric(x[i]))
Informed_pos <- sapply(Informed_pos_set4, function(x) as.numeric(x[i]))
NoisyInformed1_pos <- sapply(NoisyInformed1_pos_set4, function(x) as.numeric(x[i]))
NoisyInformed2_pos <- sapply(NoisyInformed2_pos_set4, function(x) as.numeric(x[i]))
Noisy1_pos <- sapply(Noisy1_pos_set4, function(x) as.numeric(x[i]))
Noisy2_pos <- sapply(Noisy2_pos_set4, function(x) as.numeric(x[i]))
StochNoisy_pos <- sapply(StochNoisy_pos_set4, function(x) as.numeric(x[i]))
# Calculate the average of True and Expected values for the i-th position
average_MM_pos[i, n] <- mean(MM_pos, na.rm = TRUE)
average_Informed_pos[i, n] <- mean(Informed_pos, na.rm = TRUE)
average_NoisyInformed1_pos[i, n] <- mean(NoisyInformed1_pos, na.rm = TRUE)
average_NoisyInformed2_pos[i, n] <- mean(NoisyInformed2_pos, na.rm = TRUE)
average_Noisy1_pos[i, n] <- mean(Noisy1_pos, na.rm = TRUE)
average_Noisy2_pos[i, n] <- mean(Noisy2_pos, na.rm = TRUE)
average_StochNoisy_pos[i, n] <- mean(StochNoisy_pos, na.rm = TRUE)
}
}
# Calculate the overall average for each position across all simulations
overall_average_MM_pos <- rowMeans(average_MM_pos, na.rm = TRUE)
overall_average_Informed_pos <- rowMeans(average_Informed_pos, na.rm = TRUE)
overall_average_NoisyInformed1_pos <- rowMeans(average_NoisyInformed1_pos, na.rm = TRUE)
overall_average_NoisyInformed2_pos <- rowMeans(average_NoisyInformed2_pos, na.rm = TRUE)
overall_average_Noisy1_pos <- rowMeans(average_Noisy1_pos, na.rm = TRUE)
overall_average_Noisy2_pos <- rowMeans(average_Noisy2_pos, na.rm = TRUE)
overall_average_StochNoisy_pos <- rowMeans(average_StochNoisy_pos, na.rm = TRUE)
# Plot the overall averages
plot(overall_average_MM_pos, type = "l", pch = 16, col = "black", main = "Overall Average Position", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_MM_pos, overall_average_Informed_pos, overall_average_NoisyInformed1_pos, overall_average_NoisyInformed2_pos, overall_average_Noisy1_pos, overall_average_Noisy2_pos, overall_average_StochNoisy_pos)), max(c(overall_average_MM_pos, overall_average_Informed_pos, overall_average_NoisyInformed1_pos, overall_average_NoisyInformed2_pos, overall_average_Noisy1_pos, overall_average_Noisy2_pos, overall_average_StochNoisy_pos))))
lines(overall_average_Informed_pos, type = "l", pch = 16, col = "red")
lines(overall_average_NoisyInformed1_pos, type = "l", pch = 16, col = "green")
lines(overall_average_NoisyInformed2_pos, type = "l", pch = 16, col = "yellow")
lines(overall_average_Noisy1_pos, type = "l", pch = 16, col = "blue")
lines(overall_average_Noisy2_pos, type = "l", pch = 16, col = "purple")
lines(overall_average_StochNoisy_pos, type = "l", pch = 16, col = "orange")
# Add legend
legend("bottomleft", legend = c("Market Maker", "Informed", "Noisy Informed 1", "Noisy Informed 2", "Noisy 1", "Noisy 2", "Stochastic Noisy"), col = c("black", "red", "green", "yellow", "blue", "purple", "orange"), lty = 1, cex = 0.8)

set 5 (Noisy*6)
# Initialize matrices to store averages for each position
average_true <- matrix(NA, nrow = 100, ncol = 10)
average_expected <- matrix(NA, nrow = 100, ncol = 10)
# Loop through each simulation (n)
for (n in 1:10) {
# Extract True values from the aggregated_results_4 dataframe
TrueValues_set5 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_5[n, 2])), ", ")
# Extract Expected values from the aggregated_results_4 dataframe
ExpectedValues_set5 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_4[n, 3])), ", ")
# Loop through each position (i)
for (i in 1:100) {
# Extract True and Expected values for the i-th position
True_values <- sapply(TrueValues_set5, function(x) as.numeric(x[i]))
Expected_values <- sapply(ExpectedValues_set5, function(x) as.numeric(x[i]))
# Calculate the average of True and Expected values for the i-th position
average_true[i, n] <- mean(True_values, na.rm = TRUE)
average_expected[i, n] <- mean(Expected_values, na.rm = TRUE)
}
}
# Calculate the overall average for each position across all simulations
overall_average_true <- rowMeans(average_true, na.rm = TRUE)
overall_average_expected <- rowMeans(average_expected, na.rm = TRUE)
# Plot the overall averages
plot(overall_average_true, type = "l", pch = 16, col = "blue", main = "Overall Average of True vs Expected Values", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_true, overall_average_expected)), max(c(overall_average_true, overall_average_expected))))
lines(overall_average_expected, type = "l", pch = 16, col = "red")
legend("topright", legend = c("True Values", "Expected Values"), col = c("blue", "red"), lty = 1, cex = 0.8)

# Initialize matrices to store averages for each position
average_bid <- matrix(NA, nrow = 100, ncol = 10)
average_ask <- matrix(NA, nrow = 100, ncol = 10)
# Loop through each simulation (n)
for (n in 1:10) {
# Extract True values from the aggregated_results_4 dataframe
Bids_set5 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_5[n, 4])), ", ")
# Extract Expected values from the aggregated_results_4 dataframe
Asks_set5 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_5[n, 5])), ", ")
# Loop through each position (i)
for (i in 1:100) {
# Extract True and Expected values for the i-th position
Bids <- sapply(Bids_set5, function(x) as.numeric(x[i]))
Asks <- sapply(Asks_set5, function(x) as.numeric(x[i]))
# Calculate the average of True and Expected values for the i-th position
average_bid[i, n] <- mean(Bids, na.rm = TRUE)
average_ask[i, n] <- mean(Asks, na.rm = TRUE)
}
}
# Calculate the overall average for each position across all simulations
overall_average_bid <- rowMeans(average_bid, na.rm = TRUE)
overall_average_ask <- rowMeans(average_ask, na.rm = TRUE)
# Plot the overall averages
plot(overall_average_bid, type = "l", pch = 16, col = "blue", main = "Overall Average of Bids vs Asks", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_bid, overall_average_ask)), max(c(overall_average_bid, overall_average_ask))))
lines(overall_average_ask, type = "l", pch = 16, col = "red")
legend("topright", legend = c("Bids", "Asks"), col = c("blue", "red"), lty = 1, cex = 0.8)

# Initialize matrices to store averages for each position
average_bid <- matrix(NA, nrow = 100, ncol = 10)
average_ask <- matrix(NA, nrow = 100, ncol = 10)
# Loop through each simulation (n)
for (n in 1:10) {
# Extract True values from the aggregated_results_4 dataframe
Bids_set5 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_5[n, 4])), ", ")
# Extract Expected values from the aggregated_results_4 dataframe
Asks_set5 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_5[n, 5])), ", ")
# Loop through each position (i)
for (i in 1:100) {
# Extract True and Expected values for the i-th position
Bids <- sapply(Bids_set5, function(x) as.numeric(x[i]))
Asks <- sapply(Asks_set5, function(x) as.numeric(x[i]))
# Calculate the average of True and Expected values for the i-th position
average_bid[i, n] <- mean(Bids, na.rm = TRUE)
average_ask[i, n] <- mean(Asks, na.rm = TRUE)
}
}
# Calculate the overall average for each position across all simulations
overall_average_bid <- rowMeans(average_bid, na.rm = TRUE)
overall_average_ask <- rowMeans(average_ask, na.rm = TRUE)
## True Value
# Initialize matrices to store averages for each position
average_true <- matrix(NA, nrow = 100, ncol = 10)
average_expected <- matrix(NA, nrow = 100, ncol = 10)
# Loop through each simulation (n)
for (n in 1:10) {
# Extract True values from the aggregated_results_4 dataframe
TrueValues_set5 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_5[n, 2])), ", ")
# Extract Expected values from the aggregated_results_4 dataframe
ExpectedValues_set5 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_5[n, 3])), ", ")
# Loop through each position (i)
for (i in 1:100) {
# Extract True and Expected values for the i-th position
True_values <- sapply(TrueValues_set5, function(x) as.numeric(x[i]))
Expected_values <- sapply(ExpectedValues_set5, function(x) as.numeric(x[i]))
# Calculate the average of True and Expected values for the i-th position
average_true[i, n] <- mean(True_values, na.rm = TRUE)
average_expected[i, n] <- mean(Expected_values, na.rm = TRUE)
}
}
# Calculate the overall average for each position across all simulations
overall_average_true <- rowMeans(average_true, na.rm = TRUE)
overall_average_expected <- rowMeans(average_expected, na.rm = TRUE)
# Plot the overall averages
#plot(overall_average_true, type = "l", pch = 16, col = "blue", main = "Overall Average of True vs Expected Values", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_true, overall_average_expected)), max(c(overall_average_true, overall_average_expected))))
#lines(overall_average_expected, type = "l", pch = 16, col = "red")
#legend("topright", legend = c("True Values", "Expected Values"), col = c("blue", "red"), lty = 1, cex = 0.8)
# Plot the overall averages
plot(overall_average_bid, type = "l", pch = 16, col = "blue", main = "Overall Average of Bids vs Asks & True vs Expected Values", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_bid, overall_average_ask, overall_average_true, overall_average_expected)), max(c(overall_average_bid, overall_average_ask, overall_average_true, overall_average_expected))))
lines(overall_average_ask, type = "l", pch = 16, col = "red")
lines(overall_average_true, type = "l", pch = 16, col = "green")
lines(overall_average_expected, type = "l", pch = 16, col = "purple")
legend("bottomleft", legend = c("Bids", "Asks", "True Value", "Expected Value"), col = c("blue", "red", "green", "purple"), lty = 1, cex = 0.8)

# Initialize matrices to store averages for each position
average_MM_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_Noisy1_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_Noisy2_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_Noisy3_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_Noisy4_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_Noisy5_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_Noisy6_pnl <- matrix(NA, nrow = 100, ncol = 10)
# Loop through each simulation (n)
for (n in 1:10) {
MM_pnl_set5 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_5[n, 6])), ", ")
Noisy1_pnl_set5 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_5[n, 8])), ", ")
Noisy2_pnl_set5 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_5[n, 10])), ", ")
Noisy3_pnl_set5 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_5[n, 12])), ", ")
Noisy4_pnl_set5 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_5[n, 14])), ", ")
Noisy5_pnl_set5 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_5[n, 16])), ", ")
Noisy6_pnl_set5 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_5[n, 18])), ", ")
# Loop through each position (i)
for (i in 1:100) {
# Extract True and Expected values for the i-th position
MM_pnl <- sapply(MM_pnl_set5, function(x) as.numeric(x[i]))
Noisy1_pnl <- sapply(Noisy1_pnl_set5, function(x) as.numeric(x[i]))
Noisy2_pnl <- sapply(Noisy2_pnl_set5, function(x) as.numeric(x[i]))
Noisy3_pnl <- sapply(Noisy3_pnl_set5, function(x) as.numeric(x[i]))
Noisy4_pnl <- sapply(Noisy4_pnl_set5, function(x) as.numeric(x[i]))
Noisy5_pnl <- sapply(Noisy5_pnl_set5, function(x) as.numeric(x[i]))
Noisy6_pnl <- sapply(Noisy6_pnl_set5, function(x) as.numeric(x[i]))
# Calculate the average of True and Expected values for the i-th position
average_MM_pnl[i, n] <- mean(MM_pnl, na.rm = TRUE)
average_Noisy1_pnl[i, n] <- mean(Noisy1_pnl, na.rm = TRUE)
average_Noisy2_pnl[i, n] <- mean(Noisy2_pnl, na.rm = TRUE)
average_Noisy3_pnl[i, n] <- mean(Noisy3_pnl, na.rm = TRUE)
average_Noisy4_pnl[i, n] <- mean(Noisy4_pnl, na.rm = TRUE)
average_Noisy5_pnl[i, n] <- mean(Noisy5_pnl, na.rm = TRUE)
average_Noisy6_pnl[i, n] <- mean(Noisy6_pnl, na.rm = TRUE)
}
}
# Calculate the overall average for each position across all simulations
overall_average_MM_pnl <- rowMeans(average_MM_pnl, na.rm = TRUE)
overall_average_Noisy1_pnl <- rowMeans(average_Noisy1_pnl, na.rm = TRUE)
overall_average_Noisy2_pnl <- rowMeans(average_Noisy2_pnl, na.rm = TRUE)
overall_average_Noisy3_pnl <- rowMeans(average_Noisy3_pnl, na.rm = TRUE)
overall_average_Noisy4_pnl <- rowMeans(average_Noisy4_pnl, na.rm = TRUE)
overall_average_Noisy5_pnl <- rowMeans(average_Noisy5_pnl, na.rm = TRUE)
overall_average_Noisy6_pnl <- rowMeans(average_Noisy6_pnl, na.rm = TRUE)
# Plot the overall averages
plot(overall_average_MM_pnl, type = "l", pch = 16, col = "black", main = "Overall Average PNL", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_MM_pnl, overall_average_Noisy1_pnl, overall_average_Noisy2_pnl, overall_average_Noisy3_pnl, overall_average_Noisy4_pnl, overall_average_Noisy5_pnl, overall_average_Noisy6_pnl)), max(c(overall_average_MM_pnl, overall_average_Noisy1_pnl, overall_average_Noisy2_pnl, overall_average_Noisy3_pnl, overall_average_Noisy4_pnl, overall_average_Noisy5_pnl, overall_average_Noisy6_pnl))))
lines(overall_average_Noisy1_pnl, type = "l", pch = 16, col = "red")
lines(overall_average_Noisy2_pnl, type = "l", pch = 16, col = "green")
lines(overall_average_Noisy3_pnl, type = "l", pch = 16, col = "yellow")
lines(overall_average_Noisy4_pnl, type = "l", pch = 16, col = "blue")
lines(overall_average_Noisy5_pnl, type = "l", pch = 16, col = "purple")
lines(overall_average_Noisy6_pnl, type = "l", pch = 16, col = "orange")
# Add legend
legend("bottomleft", legend = c("Market Maker", "Noisy 1", "Noisy 2", "Noisy 3", "Noisy 4", "Noisy 5", "Noisy 6"), col = c("black", "red", "green", "yellow", "blue", "purple", "orange"), lty = 1, cex = 0.8)

# Initialize matrices to store averages for each position
average_MM_pos <- matrix(NA, nrow = 100, ncol = 10)
average_Noisy1_pos <- matrix(NA, nrow = 100, ncol = 10)
average_Noisy2_pos <- matrix(NA, nrow = 100, ncol = 10)
average_Noisy3_pos <- matrix(NA, nrow = 100, ncol = 10)
average_Noisy4_pos <- matrix(NA, nrow = 100, ncol = 10)
average_Noisy5_pos <- matrix(NA, nrow = 100, ncol = 10)
average_Noisy6_pos <- matrix(NA, nrow = 100, ncol = 10)
# Loop through each simulation (n)
for (n in 1:10) {
MM_pos_set5 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_5[n, 7])), ", ")
Noisy1_pos_set5 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_5[n, 9])), ", ")
Noisy2_pos_set5 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_5[n, 11])), ", ")
Noisy3_pos_set5 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_5[n, 13])), ", ")
Noisy4_pos_set5 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_5[n, 15])), ", ")
Noisy5_pos_set5 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_5[n, 17])), ", ")
Noisy6_pos_set5 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_5[n, 19])), ", ")
# Loop through each position (i)
for (i in 1:100) {
# Extract True and Expected values for the i-th position
MM_pos <- sapply(MM_pos_set5, function(x) as.numeric(x[i]))
Noisy1_pos <- sapply(Noisy1_pos_set5, function(x) as.numeric(x[i]))
Noisy2_pos <- sapply(Noisy2_pos_set5, function(x) as.numeric(x[i]))
Noisy3_pos <- sapply(Noisy3_pos_set5, function(x) as.numeric(x[i]))
Noisy4_pos <- sapply(Noisy4_pos_set5, function(x) as.numeric(x[i]))
Noisy5_pos <- sapply(Noisy5_pos_set5, function(x) as.numeric(x[i]))
Noisy6_pos <- sapply(Noisy6_pos_set5, function(x) as.numeric(x[i]))
# Calculate the average of True and Expected values for the i-th position
average_MM_pos[i, n] <- mean(MM_pos, na.rm = TRUE)
average_Noisy1_pos[i, n] <- mean(Noisy1_pos, na.rm = TRUE)
average_Noisy2_pos[i, n] <- mean(Noisy2_pos, na.rm = TRUE)
average_Noisy3_pos[i, n] <- mean(Noisy3_pos, na.rm = TRUE)
average_Noisy4_pos[i, n] <- mean(Noisy4_pos, na.rm = TRUE)
average_Noisy5_pos[i, n] <- mean(Noisy5_pos, na.rm = TRUE)
average_Noisy6_pos[i, n] <- mean(Noisy6_pos, na.rm = TRUE)
}
}
# Calculate the overall average for each position across all simulations
overall_average_MM_pos <- rowMeans(average_MM_pos, na.rm = TRUE)
overall_average_Noisy1_pos <- rowMeans(average_Noisy1_pos, na.rm = TRUE)
overall_average_Noisy2_pos <- rowMeans(average_Noisy2_pos, na.rm = TRUE)
overall_average_Noisy3_pos <- rowMeans(average_Noisy3_pos, na.rm = TRUE)
overall_average_Noisy4_pos <- rowMeans(average_Noisy4_pos, na.rm = TRUE)
overall_average_Noisy5_pos <- rowMeans(average_Noisy5_pos, na.rm = TRUE)
overall_average_Noisy6_pos <- rowMeans(average_Noisy6_pos, na.rm = TRUE)
# Plot the overall averages
plot(overall_average_MM_pos, type = "l", pch = 16, col = "black", main = "Overall Average Position", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_MM_pos, overall_average_Noisy1_pos, overall_average_Noisy2_pos, overall_average_Noisy3_pos, overall_average_Noisy4_pos, overall_average_Noisy5_pos, overall_average_Noisy6_pos)), max(c(overall_average_MM_pos, overall_average_Noisy1_pos, overall_average_Noisy2_pos, overall_average_Noisy3_pos, overall_average_Noisy4_pos, overall_average_Noisy5_pos, overall_average_Noisy6_pos))))
lines(overall_average_Noisy1_pos, type = "l", pch = 16, col = "red")
lines(overall_average_Noisy2_pos, type = "l", pch = 16, col = "green")
lines(overall_average_Noisy3_pos, type = "l", pch = 16, col = "yellow")
lines(overall_average_Noisy4_pos, type = "l", pch = 16, col = "blue")
lines(overall_average_Noisy5_pos, type = "l", pch = 16, col = "purple")
lines(overall_average_Noisy6_pos, type = "l", pch = 16, col = "orange")
# Add legend
legend("bottomright", legend = c("Market Maker", "Noisy 1", "Noisy 2", "Noisy 3", "Noisy 4", "Noisy 5", "Noisy 6"), col = c("black", "red", "green", "yellow", "blue", "purple", "orange"), lty = 1, cex = 0.8)

set6 (1 informed + 5 noisy)
# Initialize matrices to store averages for each position
average_true <- matrix(NA, nrow = 100, ncol = 10)
average_expected <- matrix(NA, nrow = 100, ncol = 10)
# Loop through each simulation (n)
for (n in 1:10) {
# Extract True values from the aggregated_results_4 dataframe
TrueValues_set6 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_6[n, 2])), ", ")
# Extract Expected values from the aggregated_results_4 dataframe
ExpectedValues_set6 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_6[n, 3])), ", ")
# Loop through each position (i)
for (i in 1:100) {
# Extract True and Expected values for the i-th position
True_values <- sapply(TrueValues_set6, function(x) as.numeric(x[i]))
Expected_values <- sapply(ExpectedValues_set6, function(x) as.numeric(x[i]))
# Calculate the average of True and Expected values for the i-th position
average_true[i, n] <- mean(True_values, na.rm = TRUE)
average_expected[i, n] <- mean(Expected_values, na.rm = TRUE)
}
}
# Calculate the overall average for each position across all simulations
overall_average_true <- rowMeans(average_true, na.rm = TRUE)
overall_average_expected <- rowMeans(average_expected, na.rm = TRUE)
# Plot the overall averages
plot(overall_average_true, type = "l", pch = 16, col = "blue", main = "Overall Average of True vs Expected Values", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_true, overall_average_expected)), max(c(overall_average_true, overall_average_expected))))
lines(overall_average_expected, type = "l", pch = 16, col = "red")
legend("topright", legend = c("True Values", "Expected Values"), col = c("blue", "red"), lty = 1, cex = 0.8)

# Initialize matrices to store averages for each position
average_bid <- matrix(NA, nrow = 100, ncol = 10)
average_ask <- matrix(NA, nrow = 100, ncol = 10)
# Loop through each simulation (n)
for (n in 1:10) {
# Extract True values from the aggregated_results_4 dataframe
Bids_set6 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_6[n, 4])), ", ")
# Extract Expected values from the aggregated_results_4 dataframe
Asks_set6 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_6[n, 5])), ", ")
# Loop through each position (i)
for (i in 1:100) {
# Extract True and Expected values for the i-th position
Bids <- sapply(Bids_set6, function(x) as.numeric(x[i]))
Asks <- sapply(Asks_set6, function(x) as.numeric(x[i]))
# Calculate the average of True and Expected values for the i-th position
average_bid[i, n] <- mean(Bids, na.rm = TRUE)
average_ask[i, n] <- mean(Asks, na.rm = TRUE)
}
}
# Calculate the overall average for each position across all simulations
overall_average_bid <- rowMeans(average_bid, na.rm = TRUE)
overall_average_ask <- rowMeans(average_ask, na.rm = TRUE)
# Plot the overall averages
plot(overall_average_bid, type = "l", pch = 16, col = "blue", main = "Overall Average of Bids vs Asks", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_bid, overall_average_ask)), max(c(overall_average_bid, overall_average_ask))))
lines(overall_average_ask, type = "l", pch = 16, col = "red")
legend("topright", legend = c("Bids", "Asks"), col = c("blue", "red"), lty = 1, cex = 0.8)

# Initialize matrices to store averages for each position
average_bid <- matrix(NA, nrow = 100, ncol = 10)
average_ask <- matrix(NA, nrow = 100, ncol = 10)
# Loop through each simulation (n)
for (n in 1:10) {
# Extract True values from the aggregated_results_4 dataframe
Bids_set6 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_6[n, 4])), ", ")
# Extract Expected values from the aggregated_results_4 dataframe
Asks_set6 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_6[n, 5])), ", ")
# Loop through each position (i)
for (i in 1:100) {
# Extract True and Expected values for the i-th position
Bids <- sapply(Bids_set6, function(x) as.numeric(x[i]))
Asks <- sapply(Asks_set6, function(x) as.numeric(x[i]))
# Calculate the average of True and Expected values for the i-th position
average_bid[i, n] <- mean(Bids, na.rm = TRUE)
average_ask[i, n] <- mean(Asks, na.rm = TRUE)
}
}
# Calculate the overall average for each position across all simulations
overall_average_bid <- rowMeans(average_bid, na.rm = TRUE)
overall_average_ask <- rowMeans(average_ask, na.rm = TRUE)
## True Value
# Initialize matrices to store averages for each position
average_true <- matrix(NA, nrow = 100, ncol = 10)
average_expected <- matrix(NA, nrow = 100, ncol = 10)
# Loop through each simulation (n)
for (n in 1:10) {
# Extract True values from the aggregated_results_4 dataframe
TrueValues_set6 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_6[n, 2])), ", ")
# Extract Expected values from the aggregated_results_4 dataframe
ExpectedValues_set6 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_6[n, 3])), ", ")
# Loop through each position (i)
for (i in 1:100) {
# Extract True and Expected values for the i-th position
True_values <- sapply(TrueValues_set6, function(x) as.numeric(x[i]))
Expected_values <- sapply(ExpectedValues_set6, function(x) as.numeric(x[i]))
# Calculate the average of True and Expected values for the i-th position
average_true[i, n] <- mean(True_values, na.rm = TRUE)
average_expected[i, n] <- mean(Expected_values, na.rm = TRUE)
}
}
# Calculate the overall average for each position across all simulations
overall_average_true <- rowMeans(average_true, na.rm = TRUE)
overall_average_expected <- rowMeans(average_expected, na.rm = TRUE)
# Plot the overall averages
#plot(overall_average_true, type = "l", pch = 16, col = "blue", main = "Overall Average of True vs Expected Values", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_true, overall_average_expected)), max(c(overall_average_true, overall_average_expected))))
#lines(overall_average_expected, type = "l", pch = 16, col = "red")
#legend("topright", legend = c("True Values", "Expected Values"), col = c("blue", "red"), lty = 1, cex = 0.8)
# Plot the overall averages
plot(overall_average_bid, type = "l", pch = 16, col = "blue", main = "Overall Average of Bids vs Asks & True vs Expected Values", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_bid, overall_average_ask, overall_average_true, overall_average_expected)), max(c(overall_average_bid, overall_average_ask, overall_average_true, overall_average_expected))))
lines(overall_average_ask, type = "l", pch = 16, col = "red")
lines(overall_average_true, type = "l", pch = 16, col = "green")
lines(overall_average_expected, type = "l", pch = 16, col = "purple")
legend("bottomleft", legend = c("Bids", "Asks", "True Value", "Expected Value"), col = c("blue", "red", "green", "purple"), lty = 1, cex = 0.8)

# Initialize matrices to store averages for each position
average_MM_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_Informed_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_Noisy1_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_Noisy2_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_Noisy3_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_Noisy4_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_Noisy5_pnl <- matrix(NA, nrow = 100, ncol = 10)
# Loop through each simulation (n)
for (n in 1:10) {
MM_pnl_set6 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_6[n, 6])), ", ")
Informed_pnl_set6 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_6[n, 8])), ", ")
Noisy1_pnl_set6 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_6[n, 10])), ", ")
Noisy2_pnl_set6 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_6[n, 12])), ", ")
Noisy3_pnl_set6 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_6[n, 14])), ", ")
Noisy4_pnl_set6 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_6[n, 16])), ", ")
Noisy5_pnl_set6 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_6[n, 18])), ", ")
# Loop through each position (i)
for (i in 1:100) {
# Extract True and Expected values for the i-th position
MM_pnl <- sapply(MM_pnl_set6, function(x) as.numeric(x[i]))
Informed_pnl <- sapply(Informed_pnl_set6, function(x) as.numeric(x[i]))
Noisy1_pnl <- sapply(Noisy1_pnl_set6, function(x) as.numeric(x[i]))
Noisy2_pnl <- sapply(Noisy2_pnl_set6, function(x) as.numeric(x[i]))
Noisy3_pnl <- sapply(Noisy3_pnl_set6, function(x) as.numeric(x[i]))
Noisy4_pnl <- sapply(Noisy4_pnl_set6, function(x) as.numeric(x[i]))
Noisy5_pnl <- sapply(Noisy5_pnl_set6, function(x) as.numeric(x[i]))
# Calculate the average of True and Expected values for the i-th position
average_MM_pnl[i, n] <- mean(MM_pnl, na.rm = TRUE)
average_Informed_pnl[i, n] <- mean(Informed_pnl, na.rm = TRUE)
average_Noisy1_pnl[i, n] <- mean(Noisy1_pnl, na.rm = TRUE)
average_Noisy2_pnl[i, n] <- mean(Noisy2_pnl, na.rm = TRUE)
average_Noisy3_pnl[i, n] <- mean(Noisy3_pnl, na.rm = TRUE)
average_Noisy4_pnl[i, n] <- mean(Noisy4_pnl, na.rm = TRUE)
average_Noisy5_pnl[i, n] <- mean(Noisy5_pnl, na.rm = TRUE)
}
}
# Calculate the overall average for each position across all simulations
overall_average_MM_pnl <- rowMeans(average_MM_pnl, na.rm = TRUE)
overall_average_Informed_pnl <- rowMeans(average_Informed_pnl, na.rm = TRUE)
overall_average_Noisy1_pnl <- rowMeans(average_Noisy1_pnl, na.rm = TRUE)
overall_average_Noisy2_pnl <- rowMeans(average_Noisy2_pnl, na.rm = TRUE)
overall_average_Noisy3_pnl <- rowMeans(average_Noisy3_pnl, na.rm = TRUE)
overall_average_Noisy4_pnl <- rowMeans(average_Noisy4_pnl, na.rm = TRUE)
overall_average_Noisy5_pnl <- rowMeans(average_Noisy5_pnl, na.rm = TRUE)
# Plot the overall averages
plot(overall_average_MM_pnl, type = "l", pch = 16, col = "black", main = "Overall Average PNL", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_MM_pnl, overall_average_Informed_pnl, overall_average_Noisy1_pnl, overall_average_Noisy2_pnl, overall_average_Noisy3_pnl, overall_average_Noisy4_pnl, overall_average_Noisy5_pnl)), max(c(overall_average_MM_pnl, overall_average_Informed_pnl, overall_average_Noisy1_pnl, overall_average_Noisy2_pnl, overall_average_Noisy3_pnl, overall_average_Noisy4_pnl, overall_average_Noisy5_pnl))))
lines(overall_average_Informed_pnl, type = "l", pch = 16, col = "red")
lines(overall_average_Noisy1_pnl, type = "l", pch = 16, col = "green")
lines(overall_average_Noisy2_pnl, type = "l", pch = 16, col = "yellow")
lines(overall_average_Noisy3_pnl, type = "l", pch = 16, col = "blue")
lines(overall_average_Noisy4_pnl, type = "l", pch = 16, col = "purple")
lines(overall_average_Noisy5_pnl, type = "l", pch = 16, col = "orange")
# Add legend
legend("bottomleft", legend = c("Market Maker", "Informed", "Noisy 1", "Noisy 2", "Noisy 3", "Noisy 4", "Noisy 5"), col = c("black", "red", "green", "yellow", "blue", "purple", "orange"), lty = 1, cex = 0.8)

# Initialize matrices to store averages for each position
average_MM_pos <- matrix(NA, nrow = 100, ncol = 10)
average_Informed_pos <- matrix(NA, nrow = 100, ncol = 10)
average_Noisy1_pos <- matrix(NA, nrow = 100, ncol = 10)
average_Noisy2_pos <- matrix(NA, nrow = 100, ncol = 10)
average_Noisy3_pos <- matrix(NA, nrow = 100, ncol = 10)
average_Noisy4_pos <- matrix(NA, nrow = 100, ncol = 10)
average_Noisy5_pos <- matrix(NA, nrow = 100, ncol = 10)
# Loop through each simulation (n)
for (n in 1:10) {
MM_pos_set6 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_6[n, 7])), ", ")
Informed_pos_set6 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_6[n, 9])), ", ")
Noisy1_pos_set6 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_6[n, 11])), ", ")
Noisy2_pos_set6 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_6[n, 13])), ", ")
Noisy3_pos_set6 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_6[n, 15])), ", ")
Noisy4_pos_set6 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_6[n, 17])), ", ")
Noisy5_pos_set6 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_6[n, 19])), ", ")
# Loop through each position (i)
for (i in 1:100) {
# Extract True and Expected values for the i-th position
MM_pos <- sapply(MM_pos_set6, function(x) as.numeric(x[i]))
Informed_pos <- sapply(Informed_pnl_set6, function(x) as.numeric(x[i]))
Noisy1_pos <- sapply(Noisy1_pos_set6, function(x) as.numeric(x[i]))
Noisy2_pos <- sapply(Noisy2_pos_set6, function(x) as.numeric(x[i]))
Noisy3_pos <- sapply(Noisy3_pos_set6, function(x) as.numeric(x[i]))
Noisy4_pos <- sapply(Noisy4_pos_set6, function(x) as.numeric(x[i]))
Noisy5_pos <- sapply(Noisy5_pos_set6, function(x) as.numeric(x[i]))
# Calculate the average of True and Expected values for the i-th position
average_MM_pos[i, n] <- mean(MM_pos, na.rm = TRUE)
average_Informed_pos[i, n] <- mean(Informed_pos, na.rm = TRUE)
average_Noisy1_pos[i, n] <- mean(Noisy1_pos, na.rm = TRUE)
average_Noisy2_pos[i, n] <- mean(Noisy2_pos, na.rm = TRUE)
average_Noisy3_pos[i, n] <- mean(Noisy3_pos, na.rm = TRUE)
average_Noisy4_pos[i, n] <- mean(Noisy4_pos, na.rm = TRUE)
average_Noisy5_pos[i, n] <- mean(Noisy5_pos, na.rm = TRUE)
}
}
# Calculate the overall average for each position across all simulations
overall_average_MM_pos <- rowMeans(average_MM_pos, na.rm = TRUE)
overall_average_Informed_pos <- rowMeans(average_Informed_pos, na.rm = TRUE)
overall_average_Noisy1_pos <- rowMeans(average_Noisy1_pos, na.rm = TRUE)
overall_average_Noisy2_pos <- rowMeans(average_Noisy2_pos, na.rm = TRUE)
overall_average_Noisy3_pos <- rowMeans(average_Noisy3_pos, na.rm = TRUE)
overall_average_Noisy4_pos <- rowMeans(average_Noisy4_pos, na.rm = TRUE)
overall_average_Noisy5_pos <- rowMeans(average_Noisy5_pos, na.rm = TRUE)
# Plot the overall averages
plot(overall_average_MM_pos, type = "l", pch = 16, col = "black", main = "Overall Average Position", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_MM_pos, overall_average_Informed_pos, overall_average_Noisy1_pos, overall_average_Noisy2_pos, overall_average_Noisy3_pos, overall_average_Noisy4_pos, overall_average_Noisy5_pos)), max(c(overall_average_MM_pos, overall_average_Informed_pos, overall_average_Noisy1_pos, overall_average_Noisy2_pos, overall_average_Noisy3_pos, overall_average_Noisy4_pos, overall_average_Noisy5_pos))))
lines(overall_average_Informed_pos, type = "l", pch = 16, col = "red")
lines(overall_average_Noisy1_pos, type = "l", pch = 16, col = "green")
lines(overall_average_Noisy2_pos, type = "l", pch = 16, col = "yellow")
lines(overall_average_Noisy3_pos, type = "l", pch = 16, col = "blue")
lines(overall_average_Noisy4_pos, type = "l", pch = 16, col = "purple")
lines(overall_average_Noisy5_pos, type = "l", pch = 16, col = "orange")
# Add legend
legend("bottomleft", legend = c("Market Maker", "Informed", "Noisy 1", "Noisy 2", "Noisy 3", "Noisy 4", "Noisy 5"), col = c("black", "red", "green", "yellow", "blue", "purple", "orange"), lty = 1, cex = 0.8)

set7 (1 informed + 5 noisy informed)
# Initialize matrices to store averages for each position
average_true <- matrix(NA, nrow = 100, ncol = 10)
average_expected <- matrix(NA, nrow = 100, ncol = 10)
# Loop through each simulation (n)
for (n in 1:10) {
# Extract True values from the aggregated_results_4 dataframe
TrueValues_set7 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_7[n, 2])), ", ")
# Extract Expected values from the aggregated_results_4 dataframe
ExpectedValues_set7 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_7[n, 3])), ", ")
# Loop through each position (i)
for (i in 1:100) {
# Extract True and Expected values for the i-th position
True_values <- sapply(TrueValues_set7, function(x) as.numeric(x[i]))
Expected_values <- sapply(ExpectedValues_set7, function(x) as.numeric(x[i]))
# Calculate the average of True and Expected values for the i-th position
average_true[i, n] <- mean(True_values, na.rm = TRUE)
average_expected[i, n] <- mean(Expected_values, na.rm = TRUE)
}
}
# Calculate the overall average for each position across all simulations
overall_average_true <- rowMeans(average_true, na.rm = TRUE)
overall_average_expected <- rowMeans(average_expected, na.rm = TRUE)
# Plot the overall averages
plot(overall_average_true, type = "l", pch = 16, col = "blue", main = "Overall Average of True vs Expected Values", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_true, overall_average_expected)), max(c(overall_average_true, overall_average_expected))))
lines(overall_average_expected, type = "l", pch = 16, col = "red")
legend("topright", legend = c("True Values", "Expected Values"), col = c("blue", "red"), lty = 1, cex = 0.8)

# Initialize matrices to store averages for each position
average_bid <- matrix(NA, nrow = 100, ncol = 10)
average_ask <- matrix(NA, nrow = 100, ncol = 10)
# Loop through each simulation (n)
for (n in 1:10) {
# Extract True values from the aggregated_results_4 dataframe
Bids_set7 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_7[n, 4])), ", ")
# Extract Expected values from the aggregated_results_4 dataframe
Asks_set7 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_7[n, 5])), ", ")
# Loop through each position (i)
for (i in 1:100) {
# Extract True and Expected values for the i-th position
Bids <- sapply(Bids_set7, function(x) as.numeric(x[i]))
Asks <- sapply(Asks_set7, function(x) as.numeric(x[i]))
# Calculate the average of True and Expected values for the i-th position
average_bid[i, n] <- mean(Bids, na.rm = TRUE)
average_ask[i, n] <- mean(Asks, na.rm = TRUE)
}
}
# Calculate the overall average for each position across all simulations
overall_average_bid <- rowMeans(average_bid, na.rm = TRUE)
overall_average_ask <- rowMeans(average_ask, na.rm = TRUE)
# Plot the overall averages
plot(overall_average_bid, type = "l", pch = 16, col = "blue", main = "Overall Average of Bids vs Asks", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_bid, overall_average_ask)), max(c(overall_average_bid, overall_average_ask))))
lines(overall_average_ask, type = "l", pch = 16, col = "red")
legend("topright", legend = c("Bids", "Asks"), col = c("blue", "red"), lty = 1, cex = 0.8)

# Initialize matrices to store averages for each position
average_bid <- matrix(NA, nrow = 100, ncol = 10)
average_ask <- matrix(NA, nrow = 100, ncol = 10)
# Loop through each simulation (n)
for (n in 1:10) {
# Extract True values from the aggregated_results_4 dataframe
Bids_set7 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_7[n, 4])), ", ")
# Extract Expected values from the aggregated_results_4 dataframe
Asks_set7 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_7[n, 5])), ", ")
# Loop through each position (i)
for (i in 1:100) {
# Extract True and Expected values for the i-th position
Bids <- sapply(Bids_set7, function(x) as.numeric(x[i]))
Asks <- sapply(Asks_set7, function(x) as.numeric(x[i]))
# Calculate the average of True and Expected values for the i-th position
average_bid[i, n] <- mean(Bids, na.rm = TRUE)
average_ask[i, n] <- mean(Asks, na.rm = TRUE)
}
}
# Calculate the overall average for each position across all simulations
overall_average_bid <- rowMeans(average_bid, na.rm = TRUE)
overall_average_ask <- rowMeans(average_ask, na.rm = TRUE)
## True Value
# Initialize matrices to store averages for each position
average_true <- matrix(NA, nrow = 100, ncol = 10)
average_expected <- matrix(NA, nrow = 100, ncol = 10)
# Loop through each simulation (n)
for (n in 1:10) {
# Extract True values from the aggregated_results_4 dataframe
TrueValues_set7 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_7[n, 2])), ", ")
# Extract Expected values from the aggregated_results_4 dataframe
ExpectedValues_set7 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_7[n, 3])), ", ")
# Loop through each position (i)
for (i in 1:100) {
# Extract True and Expected values for the i-th position
True_values <- sapply(TrueValues_set7, function(x) as.numeric(x[i]))
Expected_values <- sapply(ExpectedValues_set7, function(x) as.numeric(x[i]))
# Calculate the average of True and Expected values for the i-th position
average_true[i, n] <- mean(True_values, na.rm = TRUE)
average_expected[i, n] <- mean(Expected_values, na.rm = TRUE)
}
}
# Calculate the overall average for each position across all simulations
overall_average_true <- rowMeans(average_true, na.rm = TRUE)
overall_average_expected <- rowMeans(average_expected, na.rm = TRUE)
# Plot the overall averages
#plot(overall_average_true, type = "l", pch = 16, col = "blue", main = "Overall Average of True vs Expected Values", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_true, overall_average_expected)), max(c(overall_average_true, overall_average_expected))))
#lines(overall_average_expected, type = "l", pch = 16, col = "red")
#legend("topright", legend = c("True Values", "Expected Values"), col = c("blue", "red"), lty = 1, cex = 0.8)
# Plot the overall averages
plot(overall_average_bid, type = "l", pch = 16, col = "blue", main = "Overall Average of Bids vs Asks & True vs Expected Values", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_bid, overall_average_ask, overall_average_true, overall_average_expected)), max(c(overall_average_bid, overall_average_ask, overall_average_true, overall_average_expected))))
lines(overall_average_ask, type = "l", pch = 16, col = "red")
lines(overall_average_true, type = "l", pch = 16, col = "green")
lines(overall_average_expected, type = "l", pch = 16, col = "purple")
legend("bottomleft", legend = c("Bids", "Asks", "True Value", "Expected Value"), col = c("blue", "red", "green", "purple"), lty = 1, cex = 0.8)

# Initialize matrices to store averages for each position
average_MM_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_Informed_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_NoisyInformed1_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_NoisyInformed2_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_NoisyInformed3_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_NoisyInformed4_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_NoisyInformed5_pnl <- matrix(NA, nrow = 100, ncol = 10)
# Loop through each simulation (n)
for (n in 1:10) {
MM_pnl_set7 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_7[n, 6])), ", ")
Informed_pnl_set7 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_7[n, 8])), ", ")
NoisyInformed1_pnl_set7 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_7[n, 10])), ", ")
NoisyInformed2_pnl_set7 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_7[n, 12])), ", ")
NoisyInformed3_pnl_set7 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_7[n, 14])), ", ")
NoisyInformed4_pnl_set7 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_7[n, 16])), ", ")
NoisyInformed5_pnl_set7 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_7[n, 18])), ", ")
# Loop through each position (i)
for (i in 1:100) {
# Extract True and Expected values for the i-th position
MM_pnl <- sapply(MM_pnl_set7, function(x) as.numeric(x[i]))
Informed_pnl <- sapply(Informed_pnl_set7, function(x) as.numeric(x[i]))
NoisyInformed1_pnl <- sapply(NoisyInformed1_pnl_set7, function(x) as.numeric(x[i]))
NoisyInformed2_pnl <- sapply(NoisyInformed2_pnl_set7, function(x) as.numeric(x[i]))
NoisyInformed3_pnl <- sapply(NoisyInformed3_pnl_set7, function(x) as.numeric(x[i]))
NoisyInformed4_pnl <- sapply(NoisyInformed4_pnl_set7, function(x) as.numeric(x[i]))
NoisyInformed5_pnl <- sapply(NoisyInformed5_pnl_set7, function(x) as.numeric(x[i]))
# Calculate the average of True and Expected values for the i-th position
average_MM_pnl[i, n] <- mean(MM_pnl, na.rm = TRUE)
average_Informed_pnl[i, n] <- mean(Informed_pnl, na.rm = TRUE)
average_NoisyInformed1_pnl[i, n] <- mean(NoisyInformed1_pnl, na.rm = TRUE)
average_NoisyInformed2_pnl[i, n] <- mean(NoisyInformed2_pnl, na.rm = TRUE)
average_NoisyInformed3_pnl[i, n] <- mean(NoisyInformed3_pnl, na.rm = TRUE)
average_NoisyInformed4_pnl[i, n] <- mean(NoisyInformed4_pnl, na.rm = TRUE)
average_NoisyInformed5_pnl[i, n] <- mean(NoisyInformed5_pnl, na.rm = TRUE)
}
}
# Calculate the overall average for each position across all simulations
overall_average_MM_pnl <- rowMeans(average_MM_pnl, na.rm = TRUE)
overall_average_Informed_pnl <- rowMeans(average_Informed_pnl, na.rm = TRUE)
overall_average_NoisyInformed1_pnl <- rowMeans(average_NoisyInformed1_pnl, na.rm = TRUE)
overall_average_NoisyInformed2_pnl <- rowMeans(average_NoisyInformed2_pnl, na.rm = TRUE)
overall_average_NoisyInformed3_pnl <- rowMeans(average_NoisyInformed3_pnl, na.rm = TRUE)
overall_average_NoisyInformed4_pnl <- rowMeans(average_NoisyInformed4_pnl, na.rm = TRUE)
overall_average_NoisyInformed5_pnl <- rowMeans(average_NoisyInformed5_pnl, na.rm = TRUE)
# Plot the overall averages
plot(overall_average_MM_pnl, type = "l", pch = 16, col = "black", main = "Overall Average PNL", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_MM_pnl, overall_average_Informed_pnl, overall_average_NoisyInformed1_pnl, overall_average_NoisyInformed2_pnl, overall_average_NoisyInformed3_pnl, overall_average_NoisyInformed4_pnl, overall_average_NoisyInformed5_pnl)), max(c(overall_average_MM_pnl, overall_average_Informed_pnl, overall_average_NoisyInformed1_pnl, overall_average_NoisyInformed2_pnl, overall_average_NoisyInformed3_pnl, overall_average_NoisyInformed4_pnl, overall_average_NoisyInformed5_pnl))))
lines(overall_average_Informed_pnl, type = "l", pch = 16, col = "red")
lines(overall_average_NoisyInformed1_pnl, type = "l", pch = 16, col = "green")
lines(overall_average_NoisyInformed2_pnl, type = "l", pch = 16, col = "yellow")
lines(overall_average_NoisyInformed3_pnl, type = "l", pch = 16, col = "blue")
lines(overall_average_NoisyInformed4_pnl, type = "l", pch = 16, col = "purple")
lines(overall_average_NoisyInformed5_pnl, type = "l", pch = 16, col = "orange")
# Add legend
legend("bottomleft", legend = c("Market Maker", "Informed", "Noisy Informed 1", "Noisy Informed 2", "Noisy Informed 3", "Noisy Informed 4", "Noisy Informed 5"), col = c("black", "red", "green", "yellow", "blue", "purple", "orange"), lty = 1, cex = 0.8)

# Initialize matrices to store averages for each position
average_MM_pos <- matrix(NA, nrow = 100, ncol = 10)
average_Informed_pos <- matrix(NA, nrow = 100, ncol = 10)
average_NoisyInformed1_pos <- matrix(NA, nrow = 100, ncol = 10)
average_NoisyInformed2_pos <- matrix(NA, nrow = 100, ncol = 10)
average_NoisyInformed3_pos <- matrix(NA, nrow = 100, ncol = 10)
average_NoisyInformed4_pos <- matrix(NA, nrow = 100, ncol = 10)
average_NoisyInformed5_pos <- matrix(NA, nrow = 100, ncol = 10)
# Loop through each simulation (n)
for (n in 1:10) {
MM_pos_set7 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_7[n, 7])), ", ")
Informed_pos_set7 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_7[n, 9])), ", ")
NoisyInformed1_pos_set7 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_7[n, 11])), ", ")
NoisyInformed2_pos_set7 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_7[n, 13])), ", ")
NoisyInformed3_pos_set7 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_7[n, 15])), ", ")
NoisyInformed4_pos_set7 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_7[n, 17])), ", ")
NoisyInformed5_pos_set7 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_7[n, 19])), ", ")
# Loop through each position (i)
for (i in 1:100) {
# Extract True and Expected values for the i-th position
MM_pos <- sapply(MM_pos_set7, function(x) as.numeric(x[i]))
Informed_pos <- sapply(Informed_pos_set7, function(x) as.numeric(x[i]))
NoisyInformed1_pos <- sapply(NoisyInformed1_pos_set7, function(x) as.numeric(x[i]))
NoisyInformed2_pos <- sapply(NoisyInformed2_pos_set7, function(x) as.numeric(x[i]))
NoisyInformed3_pos <- sapply(NoisyInformed3_pos_set7, function(x) as.numeric(x[i]))
NoisyInformed4_pos <- sapply(NoisyInformed4_pos_set7, function(x) as.numeric(x[i]))
NoisyInformed5_pos <- sapply(NoisyInformed5_pos_set7, function(x) as.numeric(x[i]))
# Calculate the average of True and Expected values for the i-th position
average_MM_pos[i, n] <- mean(MM_pos, na.rm = TRUE)
average_Informed_pos[i, n] <- mean(Informed_pos, na.rm = TRUE)
average_NoisyInformed1_pos[i, n] <- mean(NoisyInformed1_pos, na.rm = TRUE)
average_NoisyInformed2_pos[i, n] <- mean(NoisyInformed2_pos, na.rm = TRUE)
average_NoisyInformed3_pos[i, n] <- mean(NoisyInformed3_pos, na.rm = TRUE)
average_NoisyInformed4_pos[i, n] <- mean(NoisyInformed4_pos, na.rm = TRUE)
average_NoisyInformed5_pos[i, n] <- mean(NoisyInformed5_pos, na.rm = TRUE)
}
}
# Calculate the overall average for each position across all simulations
overall_average_MM_pos <- rowMeans(average_MM_pos, na.rm = TRUE)
overall_average_Informed_pos <- rowMeans(average_Informed_pos, na.rm = TRUE)
overall_average_NoisyInformed1_pos <- rowMeans(average_NoisyInformed1_pos, na.rm = TRUE)
overall_average_NoisyInformed2_pos <- rowMeans(average_NoisyInformed2_pos, na.rm = TRUE)
overall_average_NoisyInformed3_pos <- rowMeans(average_NoisyInformed3_pos, na.rm = TRUE)
overall_average_NoisyInformed4_pos <- rowMeans(average_NoisyInformed4_pos, na.rm = TRUE)
overall_average_NoisyInformed5_pos <- rowMeans(average_NoisyInformed5_pos, na.rm = TRUE)
# Plot the overall averages
plot(overall_average_MM_pos, type = "l", pch = 16, col = "black", main = "Overall Average Position", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_MM_pos, overall_average_Informed_pos, overall_average_NoisyInformed1_pos, overall_average_NoisyInformed2_pos, overall_average_NoisyInformed3_pos, overall_average_NoisyInformed4_pos, overall_average_NoisyInformed5_pos)), max(c(overall_average_MM_pos, overall_average_Informed_pos, overall_average_NoisyInformed1_pos, overall_average_NoisyInformed2_pos, overall_average_NoisyInformed3_pos, overall_average_NoisyInformed4_pos, overall_average_NoisyInformed5_pos))))
lines(overall_average_Informed_pos, type = "l", pch = 16, col = "red")
lines(overall_average_NoisyInformed1_pos, type = "l", pch = 16, col = "green")
lines(overall_average_NoisyInformed2_pos, type = "l", pch = 16, col = "yellow")
lines(overall_average_NoisyInformed3_pos, type = "l", pch = 16, col = "blue")
lines(overall_average_NoisyInformed4_pos, type = "l", pch = 16, col = "purple")
lines(overall_average_NoisyInformed5_pos, type = "l", pch = 16, col = "orange")
# Add legend
legend("bottomleft", legend = c("Market Maker", "Informed", "Noisy Informed 1", "Noisy Informed 2", "Noisy Informed 3", "Noisy Informed 4", "Noisy Informed 5"), col = c("black", "red", "green", "yellow", "blue", "purple", "orange"), lty = 1, cex = 0.8)

set8 (1 informed + 2 noisy informed + 3 noisy)
# Initialize matrices to store averages for each position
average_true <- matrix(NA, nrow = 100, ncol = 10)
average_expected <- matrix(NA, nrow = 100, ncol = 10)
# Loop through each simulation (n)
for (n in 1:10) {
# Extract True values from the aggregated_results_4 dataframe
TrueValues_set8 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_8[n, 2])), ", ")
# Extract Expected values from the aggregated_results_4 dataframe
ExpectedValues_set8 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_8[n, 3])), ", ")
# Loop through each position (i)
for (i in 1:100) {
# Extract True and Expected values for the i-th position
True_values <- sapply(TrueValues_set8, function(x) as.numeric(x[i]))
Expected_values <- sapply(ExpectedValues_set8, function(x) as.numeric(x[i]))
# Calculate the average of True and Expected values for the i-th position
average_true[i, n] <- mean(True_values, na.rm = TRUE)
average_expected[i, n] <- mean(Expected_values, na.rm = TRUE)
}
}
# Calculate the overall average for each position across all simulations
overall_average_true <- rowMeans(average_true, na.rm = TRUE)
overall_average_expected <- rowMeans(average_expected, na.rm = TRUE)
# Plot the overall averages
plot(overall_average_true, type = "l", pch = 16, col = "blue", main = "Overall Average of True vs Expected Values", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_true, overall_average_expected)), max(c(overall_average_true, overall_average_expected))))
lines(overall_average_expected, type = "l", pch = 16, col = "red")
legend("topright", legend = c("True Values", "Expected Values"), col = c("blue", "red"), lty = 1, cex = 0.8)

# Initialize matrices to store averages for each position
average_bid <- matrix(NA, nrow = 100, ncol = 10)
average_ask <- matrix(NA, nrow = 100, ncol = 10)
# Loop through each simulation (n)
for (n in 1:10) {
# Extract True values from the aggregated_results_4 dataframe
Bids_set8 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_8[n, 4])), ", ")
# Extract Expected values from the aggregated_results_4 dataframe
Asks_set8 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_8[n, 5])), ", ")
# Loop through each position (i)
for (i in 1:100) {
# Extract True and Expected values for the i-th position
Bids <- sapply(Bids_set8, function(x) as.numeric(x[i]))
Asks <- sapply(Asks_set8, function(x) as.numeric(x[i]))
# Calculate the average of True and Expected values for the i-th position
average_bid[i, n] <- mean(Bids, na.rm = TRUE)
average_ask[i, n] <- mean(Asks, na.rm = TRUE)
}
}
# Calculate the overall average for each position across all simulations
overall_average_bid <- rowMeans(average_bid, na.rm = TRUE)
overall_average_ask <- rowMeans(average_ask, na.rm = TRUE)
# Plot the overall averages
plot(overall_average_bid, type = "l", pch = 16, col = "blue", main = "Overall Average of Bids vs Asks", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_bid, overall_average_ask)), max(c(overall_average_bid, overall_average_ask))))
lines(overall_average_ask, type = "l", pch = 16, col = "red")
legend("topright", legend = c("Bids", "Asks"), col = c("blue", "red"), lty = 1, cex = 0.8)

# Initialize matrices to store averages for each position
average_bid <- matrix(NA, nrow = 100, ncol = 10)
average_ask <- matrix(NA, nrow = 100, ncol = 10)
# Loop through each simulation (n)
for (n in 1:10) {
# Extract True values from the aggregated_results_4 dataframe
Bids_set8 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_8[n, 4])), ", ")
# Extract Expected values from the aggregated_results_4 dataframe
Asks_set8 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_8[n, 5])), ", ")
# Loop through each position (i)
for (i in 1:100) {
# Extract True and Expected values for the i-th position
Bids <- sapply(Bids_set8, function(x) as.numeric(x[i]))
Asks <- sapply(Asks_set8, function(x) as.numeric(x[i]))
# Calculate the average of True and Expected values for the i-th position
average_bid[i, n] <- mean(Bids, na.rm = TRUE)
average_ask[i, n] <- mean(Asks, na.rm = TRUE)
}
}
# Calculate the overall average for each position across all simulations
overall_average_bid <- rowMeans(average_bid, na.rm = TRUE)
overall_average_ask <- rowMeans(average_ask, na.rm = TRUE)
## True Value
# Initialize matrices to store averages for each position
average_true <- matrix(NA, nrow = 100, ncol = 10)
average_expected <- matrix(NA, nrow = 100, ncol = 10)
# Loop through each simulation (n)
for (n in 1:10) {
# Extract True values from the aggregated_results_4 dataframe
TrueValues_set8 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_8[n, 2])), ", ")
# Extract Expected values from the aggregated_results_4 dataframe
ExpectedValues_set8 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_8[n, 3])), ", ")
# Loop through each position (i)
for (i in 1:100) {
# Extract True and Expected values for the i-th position
True_values <- sapply(TrueValues_set8, function(x) as.numeric(x[i]))
Expected_values <- sapply(ExpectedValues_set8, function(x) as.numeric(x[i]))
# Calculate the average of True and Expected values for the i-th position
average_true[i, n] <- mean(True_values, na.rm = TRUE)
average_expected[i, n] <- mean(Expected_values, na.rm = TRUE)
}
}
# Calculate the overall average for each position across all simulations
overall_average_true <- rowMeans(average_true, na.rm = TRUE)
overall_average_expected <- rowMeans(average_expected, na.rm = TRUE)
# Plot the overall averages
#plot(overall_average_true, type = "l", pch = 16, col = "blue", main = "Overall Average of True vs Expected Values", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_true, overall_average_expected)), max(c(overall_average_true, overall_average_expected))))
#lines(overall_average_expected, type = "l", pch = 16, col = "red")
#legend("topright", legend = c("True Values", "Expected Values"), col = c("blue", "red"), lty = 1, cex = 0.8)
# Plot the overall averages
plot(overall_average_bid, type = "l", pch = 16, col = "blue", main = "Overall Average of Bids vs Asks & True vs Expected Values", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_bid, overall_average_ask, overall_average_true, overall_average_expected)), max(c(overall_average_bid, overall_average_ask, overall_average_true, overall_average_expected))))
lines(overall_average_ask, type = "l", pch = 16, col = "red")
lines(overall_average_true, type = "l", pch = 16, col = "green")
lines(overall_average_expected, type = "l", pch = 16, col = "purple")
legend("bottomleft", legend = c("Bids", "Asks", "True Value", "Expected Value"), col = c("blue", "red", "green", "purple"), lty = 1, cex = 0.8)

# Initialize matrices to store averages for each position
average_MM_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_Informed_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_NoisyInformed1_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_NoisyInformed2_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_Noisy1_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_Noisy2_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_Noisy3_pnl <- matrix(NA, nrow = 100, ncol = 10)
# Loop through each simulation (n)
for (n in 1:10) {
MM_pnl_set8 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_8[n, 6])), ", ")
Informed_pnl_set8 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_8[n, 8])), ", ")
NoisyInformed1_pnl_set8 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_8[n, 10])), ", ")
NoisyInformed2_pnl_set8 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_8[n, 12])), ", ")
Noisy1_pnl_set8 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_8[n, 14])), ", ")
Noisy2_pnl_set8 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_8[n, 16])), ", ")
Noisy3_pnl_set8 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_8[n, 18])), ", ")
# Loop through each position (i)
for (i in 1:100) {
# Extract True and Expected values for the i-th position
MM_pnl <- sapply(MM_pnl_set8, function(x) as.numeric(x[i]))
Informed_pnl <- sapply(Informed_pnl_set8, function(x) as.numeric(x[i]))
NoisyInformed1_pnl <- sapply(NoisyInformed1_pnl_set8, function(x) as.numeric(x[i]))
NoisyInformed2_pnl <- sapply(NoisyInformed2_pnl_set8, function(x) as.numeric(x[i]))
Noisy1_pnl <- sapply(Noisy1_pnl_set8, function(x) as.numeric(x[i]))
Noisy2_pnl <- sapply(Noisy2_pnl_set8, function(x) as.numeric(x[i]))
Noisy3_pnl <- sapply(Noisy3_pnl_set8, function(x) as.numeric(x[i]))
# Calculate the average of True and Expected values for the i-th position
average_MM_pnl[i, n] <- mean(MM_pnl, na.rm = TRUE)
average_Informed_pnl[i, n] <- mean(Informed_pnl, na.rm = TRUE)
average_NoisyInformed1_pnl[i, n] <- mean(NoisyInformed1_pnl, na.rm = TRUE)
average_NoisyInformed2_pnl[i, n] <- mean(NoisyInformed2_pnl, na.rm = TRUE)
average_Noisy1_pnl[i, n] <- mean(Noisy1_pnl, na.rm = TRUE)
average_Noisy2_pnl[i, n] <- mean(Noisy2_pnl, na.rm = TRUE)
average_Noisy3_pnl[i, n] <- mean(Noisy3_pnl, na.rm = TRUE)
}
}
# Calculate the overall average for each position across all simulations
overall_average_MM_pnl <- rowMeans(average_MM_pnl, na.rm = TRUE)
overall_average_Informed_pnl <- rowMeans(average_Informed_pnl, na.rm = TRUE)
overall_average_NoisyInformed1_pnl <- rowMeans(average_NoisyInformed1_pnl, na.rm = TRUE)
overall_average_NoisyInformed2_pnl <- rowMeans(average_NoisyInformed2_pnl, na.rm = TRUE)
overall_average_Noisy1_pnl <- rowMeans(average_Noisy1_pnl, na.rm = TRUE)
overall_average_Noisy2_pnl <- rowMeans(average_Noisy2_pnl, na.rm = TRUE)
overall_average_Noisy3_pnl <- rowMeans(average_Noisy3_pnl, na.rm = TRUE)
# Plot the overall averages
plot(overall_average_MM_pnl, type = "l", pch = 16, col = "black", main = "Overall Average PNL", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_MM_pnl, overall_average_Informed_pnl, overall_average_NoisyInformed1_pnl, overall_average_NoisyInformed2_pnl, overall_average_Noisy1_pnl, overall_average_Noisy2_pnl, overall_average_Noisy3_pnl)), max(c(overall_average_MM_pnl, overall_average_Informed_pnl, overall_average_NoisyInformed1_pnl, overall_average_NoisyInformed2_pnl, overall_average_Noisy1_pnl, overall_average_Noisy2_pnl, overall_average_Noisy3_pnl))))
lines(overall_average_Informed_pnl, type = "l", pch = 16, col = "red")
lines(overall_average_NoisyInformed1_pnl, type = "l", pch = 16, col = "green")
lines(overall_average_NoisyInformed2_pnl, type = "l", pch = 16, col = "yellow")
lines(overall_average_Noisy1_pnl, type = "l", pch = 16, col = "blue")
lines(overall_average_Noisy2_pnl, type = "l", pch = 16, col = "purple")
lines(overall_average_Noisy3_pnl, type = "l", pch = 16, col = "orange")
# Add legend
legend("bottomleft", legend = c("Market Maker", "Informed", "Noisy Informed 1", "Noisy Informed 2", "Noisy 3", "Noisy 4", "Noisy 5"), col = c("black", "red", "green", "yellow", "blue", "purple", "orange"), lty = 1, cex = 0.8)

# Initialize matrices to store averages for each position
average_MM_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_Informed_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_NoisyInformed1_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_NoisyInformed2_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_Noisy1_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_Noisy2_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_Noisy3_pnl <- matrix(NA, nrow = 100, ncol = 10)
# Loop through each simulation (n)
for (n in 1:10) {
MM_pos_set8 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_8[n, 7])), ", ")
Informed_pos_set8 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_8[n, 9])), ", ")
NoisyInformed1_pos_set8 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_8[n, 11])), ", ")
NoisyInformed2_pos_set8 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_8[n, 13])), ", ")
Noisy1_pos_set8 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_8[n, 15])), ", ")
Noisy2_pos_set8 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_8[n, 17])), ", ")
Noisy3_pos_set8 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_8[n, 19])), ", ")
# Loop through each position (i)
for (i in 1:100) {
# Extract True and Expected values for the i-th position
MM_pos <- sapply(MM_pos_set8, function(x) as.numeric(x[i]))
Informed_pos <- sapply(Informed_pos_set8, function(x) as.numeric(x[i]))
NoisyInformed1_pos <- sapply(NoisyInformed1_pos_set8, function(x) as.numeric(x[i]))
NoisyInformed2_pos <- sapply(NoisyInformed2_pos_set8, function(x) as.numeric(x[i]))
Noisy1_pos <- sapply(Noisy1_pos_set8, function(x) as.numeric(x[i]))
Noisy2_pos <- sapply(Noisy2_pos_set8, function(x) as.numeric(x[i]))
Noisy3_pos <- sapply(Noisy3_pos_set8, function(x) as.numeric(x[i]))
# Calculate the average of True and Expected values for the i-th position
average_MM_pos[i, n] <- mean(MM_pos, na.rm = TRUE)
average_Informed_pos[i, n] <- mean(Informed_pos, na.rm = TRUE)
average_NoisyInformed1_pos[i, n] <- mean(NoisyInformed1_pos, na.rm = TRUE)
average_NoisyInformed2_pos[i, n] <- mean(NoisyInformed2_pos, na.rm = TRUE)
average_Noisy1_pos[i, n] <- mean(Noisy1_pos, na.rm = TRUE)
average_Noisy2_pos[i, n] <- mean(Noisy2_pos, na.rm = TRUE)
average_Noisy3_pos[i, n] <- mean(Noisy3_pos, na.rm = TRUE)
}
}
# Calculate the overall average for each position across all simulations
overall_average_MM_pos <- rowMeans(average_MM_pos, na.rm = TRUE)
overall_average_Informed_pos <- rowMeans(average_Informed_pos, na.rm = TRUE)
overall_average_NoisyInformed1_pos <- rowMeans(average_NoisyInformed1_pos, na.rm = TRUE)
overall_average_NoisyInformed2_pos <- rowMeans(average_NoisyInformed2_pos, na.rm = TRUE)
overall_average_Noisy1_pos <- rowMeans(average_Noisy1_pos, na.rm = TRUE)
overall_average_Noisy2_pos <- rowMeans(average_Noisy2_pos, na.rm = TRUE)
overall_average_Noisy3_pos <- rowMeans(average_Noisy3_pos, na.rm = TRUE)
# Plot the overall averages
plot(overall_average_MM_pos, type = "l", pch = 16, col = "black", main = "Overall Average Position", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_MM_pos, overall_average_Informed_pos, overall_average_NoisyInformed1_pos, overall_average_NoisyInformed2_pos, overall_average_Noisy1_pos, overall_average_Noisy2_pos, overall_average_Noisy3_pos)), max(c(overall_average_MM_pos, overall_average_Informed_pos, overall_average_NoisyInformed1_pos, overall_average_NoisyInformed2_pos, overall_average_Noisy1_pos, overall_average_Noisy2_pos, overall_average_Noisy3_pos))))
lines(overall_average_Informed_pos, type = "l", pch = 16, col = "red")
lines(overall_average_NoisyInformed1_pos, type = "l", pch = 16, col = "green")
lines(overall_average_NoisyInformed2_pos, type = "l", pch = 16, col = "yellow")
lines(overall_average_Noisy1_pos, type = "l", pch = 16, col = "blue")
lines(overall_average_Noisy2_pos, type = "l", pch = 16, col = "purple")
lines(overall_average_Noisy3_pos, type = "l", pch = 16, col = "orange")
# Add legend
legend("bottomleft", legend = c("Market Maker", "Informed", "Noisy Informed 1", "Noisy Informed 2", "Noisy 3", "Noisy 4", "Noisy 5"), col = c("black", "red", "green", "yellow", "blue", "purple", "orange"), lty = 1, cex = 0.8)

set9 (Mean Reversion: 6)
# Initialize matrices to store averages for each position
average_true <- matrix(NA, nrow = 100, ncol = 10)
average_expected <- matrix(NA, nrow = 100, ncol = 10)
# Loop through each simulation (n)
for (n in 1:10) {
# Extract True values from the aggregated_results_4 dataframe
TrueValues_set9 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_9[n, 2])), ", ")
# Extract Expected values from the aggregated_results_4 dataframe
ExpectedValues_set9 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_9[n, 3])), ", ")
# Loop through each position (i)
for (i in 1:100) {
# Extract True and Expected values for the i-th position
True_values <- sapply(TrueValues_set9, function(x) as.numeric(x[i]))
Expected_values <- sapply(ExpectedValues_set9, function(x) as.numeric(x[i]))
# Calculate the average of True and Expected values for the i-th position
average_true[i, n] <- mean(True_values, na.rm = TRUE)
average_expected[i, n] <- mean(Expected_values, na.rm = TRUE)
}
}
# Calculate the overall average for each position across all simulations
overall_average_true <- rowMeans(average_true, na.rm = TRUE)
overall_average_expected <- rowMeans(average_expected, na.rm = TRUE)
# Plot the overall averages
plot(overall_average_true, type = "l", pch = 16, col = "blue", main = "Overall Average of True vs Expected Values", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_true, overall_average_expected)), max(c(overall_average_true, overall_average_expected))))
lines(overall_average_expected, type = "l", pch = 16, col = "red")
legend("topright", legend = c("True Values", "Expected Values"), col = c("blue", "red"), lty = 1, cex = 0.8)

# Initialize matrices to store averages for each position
average_bid <- matrix(NA, nrow = 100, ncol = 10)
average_ask <- matrix(NA, nrow = 100, ncol = 10)
# Loop through each simulation (n)
for (n in 1:10) {
# Extract True values from the aggregated_results_4 dataframe
Bids_set9 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_9[n, 4])), ", ")
# Extract Expected values from the aggregated_results_4 dataframe
Asks_set9 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_9[n, 5])), ", ")
# Loop through each position (i)
for (i in 1:100) {
# Extract True and Expected values for the i-th position
Bids <- sapply(Bids_set9, function(x) as.numeric(x[i]))
Asks <- sapply(Asks_set9, function(x) as.numeric(x[i]))
# Calculate the average of True and Expected values for the i-th position
average_bid[i, n] <- mean(Bids, na.rm = TRUE)
average_ask[i, n] <- mean(Asks, na.rm = TRUE)
}
}
# Calculate the overall average for each position across all simulations
overall_average_bid <- rowMeans(average_bid, na.rm = TRUE)
overall_average_ask <- rowMeans(average_ask, na.rm = TRUE)
# Plot the overall averages
plot(overall_average_bid, type = "l", pch = 16, col = "blue", main = "Overall Average of Bids vs Asks", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_bid, overall_average_ask)), max(c(overall_average_bid, overall_average_ask))))
lines(overall_average_ask, type = "l", pch = 16, col = "red")
legend("topright", legend = c("Bids", "Asks"), col = c("blue", "red"), lty = 1, cex = 0.8)

# Initialize matrices to store averages for each position
average_bid <- matrix(NA, nrow = 100, ncol = 10)
average_ask <- matrix(NA, nrow = 100, ncol = 10)
# Loop through each simulation (n)
for (n in 1:10) {
# Extract True values from the aggregated_results_4 dataframe
Bids_set9 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_9[n, 4])), ", ")
# Extract Expected values from the aggregated_results_4 dataframe
Asks_set9 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_9[n, 5])), ", ")
# Loop through each position (i)
for (i in 1:100) {
# Extract True and Expected values for the i-th position
Bids <- sapply(Bids_set9, function(x) as.numeric(x[i]))
Asks <- sapply(Asks_set9, function(x) as.numeric(x[i]))
# Calculate the average of True and Expected values for the i-th position
average_bid[i, n] <- mean(Bids, na.rm = TRUE)
average_ask[i, n] <- mean(Asks, na.rm = TRUE)
}
}
# Calculate the overall average for each position across all simulations
overall_average_bid <- rowMeans(average_bid, na.rm = TRUE)
overall_average_ask <- rowMeans(average_ask, na.rm = TRUE)
## True Value
# Initialize matrices to store averages for each position
average_true <- matrix(NA, nrow = 100, ncol = 10)
average_expected <- matrix(NA, nrow = 100, ncol = 10)
# Loop through each simulation (n)
for (n in 1:10) {
# Extract True values from the aggregated_results_4 dataframe
TrueValues_set9 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_9[n, 2])), ", ")
# Extract Expected values from the aggregated_results_4 dataframe
ExpectedValues_set9 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_9[n, 3])), ", ")
# Loop through each position (i)
for (i in 1:100) {
# Extract True and Expected values for the i-th position
True_values <- sapply(TrueValues_set9, function(x) as.numeric(x[i]))
Expected_values <- sapply(ExpectedValues_set9, function(x) as.numeric(x[i]))
# Calculate the average of True and Expected values for the i-th position
average_true[i, n] <- mean(True_values, na.rm = TRUE)
average_expected[i, n] <- mean(Expected_values, na.rm = TRUE)
}
}
# Calculate the overall average for each position across all simulations
overall_average_true <- rowMeans(average_true, na.rm = TRUE)
overall_average_expected <- rowMeans(average_expected, na.rm = TRUE)
# Plot the overall averages
#plot(overall_average_true, type = "l", pch = 16, col = "blue", main = "Overall Average of True vs Expected Values", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_true, overall_average_expected)), max(c(overall_average_true, overall_average_expected))))
#lines(overall_average_expected, type = "l", pch = 16, col = "red")
#legend("topright", legend = c("True Values", "Expected Values"), col = c("blue", "red"), lty = 1, cex = 0.8)
# Plot the overall averages
plot(overall_average_bid, type = "l", pch = 16, col = "blue", main = "Overall Average of Bids vs Asks & True vs Expected Values", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_bid, overall_average_ask, overall_average_true, overall_average_expected)), max(c(overall_average_bid, overall_average_ask, overall_average_true, overall_average_expected))))
lines(overall_average_ask, type = "l", pch = 16, col = "red")
lines(overall_average_true, type = "l", pch = 16, col = "green")
lines(overall_average_expected, type = "l", pch = 16, col = "purple")
legend("bottomleft", legend = c("Bids", "Asks", "True Value", "Expected Value"), col = c("blue", "red", "green", "purple"), lty = 1, cex = 0.8)

# Initialize matrices to store averages for each position
average_MM_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_MR1_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_MR2_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_MR3_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_MR4_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_MR5_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_MR6_pnl <- matrix(NA, nrow = 100, ncol = 10)
# Loop through each simulation (n)
for (n in 1:10) {
MM_pnl_set9 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_9[n, 6])), ", ")
MR1_pnl_set9 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_9[n, 8])), ", ")
MR2_pnl_set9 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_9[n, 10])), ", ")
MR3_pnl_set9 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_9[n, 12])), ", ")
MR4_pnl_set9 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_9[n, 14])), ", ")
MR5_pnl_set9 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_9[n, 16])), ", ")
MR6_pnl_set9 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_9[n, 18])), ", ")
# Loop through each position (i)
for (i in 1:100) {
# Extract True and Expected values for the i-th position
MM_pnl <- sapply(MM_pnl_set9, function(x) as.numeric(x[i]))
MR1_pnl <- sapply(MR1_pnl_set9, function(x) as.numeric(x[i]))
MR2_pnl <- sapply(MR2_pnl_set9, function(x) as.numeric(x[i]))
MR3_pnl <- sapply(MR3_pnl_set9, function(x) as.numeric(x[i]))
MR4_pnl <- sapply(MR4_pnl_set9, function(x) as.numeric(x[i]))
MR5_pnl <- sapply(MR5_pnl_set9, function(x) as.numeric(x[i]))
MR6_pnl <- sapply(MR6_pnl_set9, function(x) as.numeric(x[i]))
# Calculate the average of True and Expected values for the i-th position
average_MM_pnl[i, n] <- mean(MM_pnl, na.rm = TRUE)
average_MR1_pnl[i, n] <- mean(MR1_pnl, na.rm = TRUE)
average_MR2_pnl[i, n] <- mean(MR2_pnl, na.rm = TRUE)
average_MR3_pnl[i, n] <- mean(MR3_pnl, na.rm = TRUE)
average_MR4_pnl[i, n] <- mean(MR4_pnl, na.rm = TRUE)
average_MR5_pnl[i, n] <- mean(MR5_pnl, na.rm = TRUE)
average_MR6_pnl[i, n] <- mean(MR6_pnl, na.rm = TRUE)
}
}
# Calculate the overall average for each position across all simulations
overall_average_MM_pnl <- rowMeans(average_MM_pnl, na.rm = TRUE)
overall_average_MR1_pnl <- rowMeans(average_MR1_pnl, na.rm = TRUE)
overall_average_MR2_pnl <- rowMeans(average_MR2_pnl, na.rm = TRUE)
overall_average_MR3_pnl <- rowMeans(average_MR3_pnl, na.rm = TRUE)
overall_average_MR4_pnl <- rowMeans(average_MR4_pnl, na.rm = TRUE)
overall_average_MR5_pnl <- rowMeans(average_MR5_pnl, na.rm = TRUE)
overall_average_MR6_pnl <- rowMeans(average_MR6_pnl, na.rm = TRUE)
# Plot the overall averages
plot(overall_average_MM_pnl, type = "l", pch = 16, col = "black", main = "Overall Average PNL", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_MM_pnl, overall_average_MR1_pnl, overall_average_MR2_pnl, overall_average_MR3_pnl, overall_average_MR4_pnl, overall_average_MR5_pnl, overall_average_MR6_pnl)), max(c(overall_average_MM_pnl, overall_average_MR1_pnl, overall_average_MR2_pnl, overall_average_MR3_pnl, overall_average_MR4_pnl, overall_average_MR5_pnl, overall_average_MR6_pnl))))
lines(overall_average_MR1_pnl, type = "l", pch = 16, col = "red")
lines(overall_average_MR2_pnl, type = "l", pch = 16, col = "green")
lines(overall_average_MR3_pnl, type = "l", pch = 16, col = "yellow")
lines(overall_average_MR4_pnl, type = "l", pch = 16, col = "blue")
lines(overall_average_MR5_pnl, type = "l", pch = 16, col = "purple")
lines(overall_average_MR6_pnl, type = "l", pch = 16, col = "orange")
# Add legend
legend("bottomleft", legend = c("Market Maker", "MR1", "MR2", "MR3", "MR4", "MR5", "MR6"), col = c("black", "red", "green", "yellow", "blue", "purple", "orange"), lty = 1, cex = 0.8)

# Initialize matrices to store averages for each position
average_MM_pos <- matrix(NA, nrow = 100, ncol = 10)
average_MR1_pos <- matrix(NA, nrow = 100, ncol = 10)
average_MR2_pos <- matrix(NA, nrow = 100, ncol = 10)
average_MR3_pos <- matrix(NA, nrow = 100, ncol = 10)
average_MR4_pos <- matrix(NA, nrow = 100, ncol = 10)
average_MR5_pos <- matrix(NA, nrow = 100, ncol = 10)
average_MR6_pos <- matrix(NA, nrow = 100, ncol = 10)
# Loop through each simulation (n)
for (n in 1:10) {
MM_pos_set9 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_9[n, 7])), ", ")
MR1_pos_set9 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_9[n, 9])), ", ")
MR2_pos_set9 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_9[n, 11])), ", ")
MR3_pos_set9 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_9[n, 13])), ", ")
MR4_pos_set9 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_9[n, 15])), ", ")
MR5_pos_set9 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_9[n, 17])), ", ")
MR6_pos_set9 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_9[n, 19])), ", ")
# Loop through each position (i)
for (i in 1:100) {
# Extract True and Expected values for the i-th position
MM_pos <- sapply(MM_pos_set9, function(x) as.numeric(x[i]))
MR1_pos <- sapply(MR1_pos_set9, function(x) as.numeric(x[i]))
MR2_pos <- sapply(MR2_pos_set9, function(x) as.numeric(x[i]))
MR3_pos <- sapply(MR3_pos_set9, function(x) as.numeric(x[i]))
MR4_pos <- sapply(MR4_pos_set9, function(x) as.numeric(x[i]))
MR5_pos <- sapply(MR5_pos_set9, function(x) as.numeric(x[i]))
MR6_pos <- sapply(MR6_pos_set9, function(x) as.numeric(x[i]))
# Calculate the average of True and Expected values for the i-th position
average_MM_pos[i, n] <- mean(MM_pos, na.rm = TRUE)
average_MR1_pos[i, n] <- mean(MR1_pos, na.rm = TRUE)
average_MR2_pos[i, n] <- mean(MR2_pos, na.rm = TRUE)
average_MR3_pos[i, n] <- mean(MR3_pos, na.rm = TRUE)
average_MR4_pos[i, n] <- mean(MR4_pos, na.rm = TRUE)
average_MR5_pos[i, n] <- mean(MR5_pos, na.rm = TRUE)
average_MR6_pos[i, n] <- mean(MR6_pos, na.rm = TRUE)
}
}
# Calculate the overall average for each position across all simulations
overall_average_MM_pos <- rowMeans(average_MM_pos, na.rm = TRUE)
overall_average_MR1_pos <- rowMeans(average_MR1_pos, na.rm = TRUE)
overall_average_MR2_pos <- rowMeans(average_MR2_pos, na.rm = TRUE)
overall_average_MR3_pos <- rowMeans(average_MR3_pos, na.rm = TRUE)
overall_average_MR4_pos <- rowMeans(average_MR4_pos, na.rm = TRUE)
overall_average_MR5_pos <- rowMeans(average_MR5_pos, na.rm = TRUE)
overall_average_MR6_pos <- rowMeans(average_MR6_pos, na.rm = TRUE)
# Plot the overall averages
plot(overall_average_MM_pos, type = "l", pch = 16, col = "black", main = "Overall Average Position", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_MM_pos, overall_average_MR1_pos, overall_average_MR2_pos, overall_average_MR3_pos, overall_average_MR4_pos, overall_average_MR5_pos, overall_average_MR6_pos)), max(c(overall_average_MM_pos, overall_average_MR1_pos, overall_average_MR2_pos, overall_average_MR3_pos, overall_average_MR4_pos, overall_average_MR5_pos, overall_average_MR6_pos))))
lines(overall_average_MR1_pos, type = "l", pch = 16, col = "red")
lines(overall_average_MR2_pos, type = "l", pch = 16, col = "green")
lines(overall_average_MR3_pos, type = "l", pch = 16, col = "yellow")
lines(overall_average_MR4_pos, type = "l", pch = 16, col = "blue")
lines(overall_average_MR5_pos, type = "l", pch = 16, col = "purple")
lines(overall_average_MR6_pos, type = "l", pch = 16, col = "orange")
# Add legend
legend("bottomleft", legend = c("Market Maker", "MR1", "MR2", "MR3", "MR4", "MR5", "MR6"), col = c("black", "red", "green", "yellow", "blue", "purple", "orange"), lty = 1, cex = 0.8)

set10 (Mom : 6)
# Initialize matrices to store averages for each position
average_true <- matrix(NA, nrow = 100, ncol = 10)
average_expected <- matrix(NA, nrow = 100, ncol = 10)
# Loop through each simulation (n)
for (n in 1:10) {
# Extract True values from the aggregated_results_4 dataframe
TrueValues_set10 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_10[n, 2])), ", ")
# Extract Expected values from the aggregated_results_4 dataframe
ExpectedValues_set10 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_10[n, 3])), ", ")
# Loop through each position (i)
for (i in 1:100) {
# Extract True and Expected values for the i-th position
True_values <- sapply(TrueValues_set10, function(x) as.numeric(x[i]))
Expected_values <- sapply(ExpectedValues_set10, function(x) as.numeric(x[i]))
# Calculate the average of True and Expected values for the i-th position
average_true[i, n] <- mean(True_values, na.rm = TRUE)
average_expected[i, n] <- mean(Expected_values, na.rm = TRUE)
}
}
# Calculate the overall average for each position across all simulations
overall_average_true <- rowMeans(average_true, na.rm = TRUE)
overall_average_expected <- rowMeans(average_expected, na.rm = TRUE)
# Plot the overall averages
plot(overall_average_true, type = "l", pch = 16, col = "blue", main = "Overall Average of True vs Expected Values", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_true, overall_average_expected)), max(c(overall_average_true, overall_average_expected))))
lines(overall_average_expected, type = "l", pch = 16, col = "red")
legend("topright", legend = c("True Values", "Expected Values"), col = c("blue", "red"), lty = 1, cex = 0.8)

# Initialize matrices to store averages for each position
average_bid <- matrix(NA, nrow = 100, ncol = 10)
average_ask <- matrix(NA, nrow = 100, ncol = 10)
# Loop through each simulation (n)
for (n in 1:10) {
# Extract True values from the aggregated_results_4 dataframe
Bids_set10 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_10[n, 4])), ", ")
# Extract Expected values from the aggregated_results_4 dataframe
Asks_set10 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_10[n, 5])), ", ")
# Loop through each position (i)
for (i in 1:100) {
# Extract True and Expected values for the i-th position
Bids <- sapply(Bids_set10, function(x) as.numeric(x[i]))
Asks <- sapply(Asks_set10, function(x) as.numeric(x[i]))
# Calculate the average of True and Expected values for the i-th position
average_bid[i, n] <- mean(Bids, na.rm = TRUE)
average_ask[i, n] <- mean(Asks, na.rm = TRUE)
}
}
# Calculate the overall average for each position across all simulations
overall_average_bid <- rowMeans(average_bid, na.rm = TRUE)
overall_average_ask <- rowMeans(average_ask, na.rm = TRUE)
# Plot the overall averages
plot(overall_average_bid, type = "l", pch = 16, col = "blue", main = "Overall Average of Bids vs Asks", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_bid, overall_average_ask)), max(c(overall_average_bid, overall_average_ask))))
lines(overall_average_ask, type = "l", pch = 16, col = "red")
legend("topright", legend = c("Bids", "Asks"), col = c("blue", "red"), lty = 1, cex = 0.8)

# Initialize matrices to store averages for each position
average_bid <- matrix(NA, nrow = 100, ncol = 10)
average_ask <- matrix(NA, nrow = 100, ncol = 10)
# Loop through each simulation (n)
for (n in 1:10) {
# Extract True values from the aggregated_results_4 dataframe
Bids_set10 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_10[n, 4])), ", ")
# Extract Expected values from the aggregated_results_4 dataframe
Asks_set10 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_10[n, 5])), ", ")
# Loop through each position (i)
for (i in 1:100) {
# Extract True and Expected values for the i-th position
Bids <- sapply(Bids_set10, function(x) as.numeric(x[i]))
Asks <- sapply(Asks_set10, function(x) as.numeric(x[i]))
# Calculate the average of True and Expected values for the i-th position
average_bid[i, n] <- mean(Bids, na.rm = TRUE)
average_ask[i, n] <- mean(Asks, na.rm = TRUE)
}
}
# Calculate the overall average for each position across all simulations
overall_average_bid <- rowMeans(average_bid, na.rm = TRUE)
overall_average_ask <- rowMeans(average_ask, na.rm = TRUE)
## True Value
# Initialize matrices to store averages for each position
average_true <- matrix(NA, nrow = 100, ncol = 10)
average_expected <- matrix(NA, nrow = 100, ncol = 10)
# Loop through each simulation (n)
for (n in 1:10) {
# Extract True values from the aggregated_results_4 dataframe
TrueValues_set10 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_10[n, 2])), ", ")
# Extract Expected values from the aggregated_results_4 dataframe
ExpectedValues_set10 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_10[n, 3])), ", ")
# Loop through each position (i)
for (i in 1:100) {
# Extract True and Expected values for the i-th position
True_values <- sapply(TrueValues_set10, function(x) as.numeric(x[i]))
Expected_values <- sapply(ExpectedValues_set1, function(x) as.numeric(x[i]))
# Calculate the average of True and Expected values for the i-th position
average_true[i, n] <- mean(True_values, na.rm = TRUE)
average_expected[i, n] <- mean(Expected_values, na.rm = TRUE)
}
}
# Calculate the overall average for each position across all simulations
overall_average_true <- rowMeans(average_true, na.rm = TRUE)
overall_average_expected <- rowMeans(average_expected, na.rm = TRUE)
# Plot the overall averages
#plot(overall_average_true, type = "l", pch = 16, col = "blue", main = "Overall Average of True vs Expected Values", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_true, overall_average_expected)), max(c(overall_average_true, overall_average_expected))))
#lines(overall_average_expected, type = "l", pch = 16, col = "red")
#legend("topright", legend = c("True Values", "Expected Values"), col = c("blue", "red"), lty = 1, cex = 0.8)
# Plot the overall averages
plot(overall_average_bid, type = "l", pch = 16, col = "blue", main = "Overall Average of Bids vs Asks & True vs Expected Values", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_bid, overall_average_ask, overall_average_true, overall_average_expected)), max(c(overall_average_bid, overall_average_ask, overall_average_true, overall_average_expected))))
lines(overall_average_ask, type = "l", pch = 16, col = "red")
lines(overall_average_true, type = "l", pch = 16, col = "green")
lines(overall_average_expected, type = "l", pch = 16, col = "purple")
legend("bottomleft", legend = c("Bids", "Asks", "True Value", "Expected Value"), col = c("blue", "red", "green", "purple"), lty = 1, cex = 0.8)

# Initialize matrices to store averages for each position
average_MM_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_Mom1_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_Mom2_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_Mom3_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_Mom4_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_Mom5_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_Mom6_pnl <- matrix(NA, nrow = 100, ncol = 10)
# Loop through each simulation (n)
for (n in 1:10) {
MM_pnl_set10 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_10[n, 6])), ", ")
Mom1_pnl_set10 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_10[n, 8])), ", ")
Mom2_pnl_set10 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_10[n, 10])), ", ")
Mom3_pnl_set10 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_10[n, 12])), ", ")
Mom4_pnl_set10 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_10[n, 14])), ", ")
Mom5_pnl_set10 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_10[n, 16])), ", ")
Mom6_pnl_set10 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_10[n, 18])), ", ")
# Loop through each position (i)
for (i in 1:100) {
# Extract True and Expected values for the i-th position
MM_pnl <- sapply(MM_pnl_set10, function(x) as.numeric(x[i]))
Mom1_pnl <- sapply(Mom1_pnl_set10, function(x) as.numeric(x[i]))
Mom2_pnl <- sapply(Mom2_pnl_set10, function(x) as.numeric(x[i]))
Mom3_pnl <- sapply(Mom3_pnl_set10, function(x) as.numeric(x[i]))
Mom4_pnl <- sapply(Mom4_pnl_set10, function(x) as.numeric(x[i]))
Mom5_pnl <- sapply(Mom5_pnl_set10, function(x) as.numeric(x[i]))
Mom6_pnl <- sapply(Mom6_pnl_set10, function(x) as.numeric(x[i]))
# Calculate the average of True and Expected values for the i-th position
average_MM_pnl[i, n] <- mean(MM_pnl, na.rm = TRUE)
average_Mom1_pnl[i, n] <- mean(Mom1_pnl, na.rm = TRUE)
average_Mom2_pnl[i, n] <- mean(Mom2_pnl, na.rm = TRUE)
average_Mom3_pnl[i, n] <- mean(Mom3_pnl, na.rm = TRUE)
average_Mom4_pnl[i, n] <- mean(Mom4_pnl, na.rm = TRUE)
average_Mom5_pnl[i, n] <- mean(Mom5_pnl, na.rm = TRUE)
average_Mom6_pnl[i, n] <- mean(Mom6_pnl, na.rm = TRUE)
}
}
# Calculate the overall average for each position across all simulations
overall_average_MM_pnl <- rowMeans(average_MM_pnl, na.rm = TRUE)
overall_average_Mom1_pnl <- rowMeans(average_Mom1_pnl, na.rm = TRUE)
overall_average_Mom2_pnl <- rowMeans(average_Mom2_pnl, na.rm = TRUE)
overall_average_Mom3_pnl <- rowMeans(average_Mom3_pnl, na.rm = TRUE)
overall_average_Mom4_pnl <- rowMeans(average_Mom4_pnl, na.rm = TRUE)
overall_average_Mom5_pnl <- rowMeans(average_Mom5_pnl, na.rm = TRUE)
overall_average_Mom6_pnl <- rowMeans(average_Mom6_pnl, na.rm = TRUE)
# Plot the overall averages
plot(overall_average_MM_pnl, type = "l", pch = 16, col = "black", main = "Overall Average PNL", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_MM_pnl, overall_average_Mom1_pnl, overall_average_Mom2_pnl, overall_average_Mom3_pnl, overall_average_Mom4_pnl, overall_average_Mom5_pnl, overall_average_Mom6_pnl)), max(c(overall_average_MM_pnl, overall_average_Mom1_pnl, overall_average_Mom2_pnl, overall_average_Mom3_pnl, overall_average_Mom4_pnl, overall_average_Mom5_pnl, overall_average_Mom6_pnl))))
lines(overall_average_Mom1_pnl, type = "l", pch = 16, col = "red")
lines(overall_average_Mom2_pnl, type = "l", pch = 16, col = "green")
lines(overall_average_Mom3_pnl, type = "l", pch = 16, col = "yellow")
lines(overall_average_Mom4_pnl, type = "l", pch = 16, col = "blue")
lines(overall_average_Mom5_pnl, type = "l", pch = 16, col = "purple")
lines(overall_average_Mom6_pnl, type = "l", pch = 16, col = "orange")
# Add legend
legend("bottomleft", legend = c("Market Maker", "Informed", "Mom1", "Mom2", "Mom3", "Mom4", "Mom5"), col = c("black", "red", "green", "yellow", "blue", "purple", "orange"), lty = 1, cex = 0.8)

# Initialize matrices to store averages for each position
average_MM_pos <- matrix(NA, nrow = 100, ncol = 10)
average_Mom1_pos <- matrix(NA, nrow = 100, ncol = 10)
average_Mom2_pos <- matrix(NA, nrow = 100, ncol = 10)
average_Mom3_pos <- matrix(NA, nrow = 100, ncol = 10)
average_Mom4_pos <- matrix(NA, nrow = 100, ncol = 10)
average_Mom5_pos <- matrix(NA, nrow = 100, ncol = 10)
average_Mom6_pos <- matrix(NA, nrow = 100, ncol = 10)
# Loop through each simulation (n)
for (n in 1:10) {
MM_pos_set10 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_10[n, 7])), ", ")
Mom1_pos_set10 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_10[n, 9])), ", ")
Mom2_pos_set10 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_10[n, 11])), ", ")
Mom3_pos_set10 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_10[n, 13])), ", ")
Mom4_pos_set10 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_10[n, 15])), ", ")
Mom5_pos_set10 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_10[n, 17])), ", ")
Mom6_pos_set10 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_10[n, 19])), ", ")
# Loop through each position (i)
for (i in 1:100) {
# Extract True and Expected values for the i-th position
MM_pos <- sapply(MM_pos_set10, function(x) as.numeric(x[i]))
Mom1_pos <- sapply(Mom1_pos_set10, function(x) as.numeric(x[i]))
Mom2_pos <- sapply(Mom2_pos_set10, function(x) as.numeric(x[i]))
Mom3_pos <- sapply(Mom3_pos_set10, function(x) as.numeric(x[i]))
Mom4_pos <- sapply(Mom4_pos_set10, function(x) as.numeric(x[i]))
Mom5_pos <- sapply(Mom5_pos_set10, function(x) as.numeric(x[i]))
Mom6_pos <- sapply(Mom6_pos_set10, function(x) as.numeric(x[i]))
# Calculate the average of True and Expected values for the i-th position
average_MM_pos[i, n] <- mean(MM_pos, na.rm = TRUE)
average_Mom1_pos[i, n] <- mean(Mom1_pos, na.rm = TRUE)
average_Mom2_pos[i, n] <- mean(Mom2_pos, na.rm = TRUE)
average_Mom3_pos[i, n] <- mean(Mom3_pos, na.rm = TRUE)
average_Mom4_pos[i, n] <- mean(Mom4_pos, na.rm = TRUE)
average_Mom5_pos[i, n] <- mean(Mom5_pos, na.rm = TRUE)
average_Mom6_pos[i, n] <- mean(Mom6_pos, na.rm = TRUE)
}
}
# Calculate the overall average for each position across all simulations
overall_average_MM_pos <- rowMeans(average_MM_pos, na.rm = TRUE)
overall_average_Mom1_pos <- rowMeans(average_Mom1_pos, na.rm = TRUE)
overall_average_Mom2_pos <- rowMeans(average_Mom2_pos, na.rm = TRUE)
overall_average_Mom3_pos <- rowMeans(average_Mom3_pos, na.rm = TRUE)
overall_average_Mom4_pos <- rowMeans(average_Mom4_pos, na.rm = TRUE)
overall_average_Mom5_pos <- rowMeans(average_Mom5_pos, na.rm = TRUE)
overall_average_Mom6_pos <- rowMeans(average_Mom6_pos, na.rm = TRUE)
# Plot the overall averages
plot(overall_average_MM_pos, type = "l", pch = 16, col = "black", main = "Overall Average Position", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_MM_pos, overall_average_Mom1_pos, overall_average_Mom2_pos, overall_average_Mom3_pos, overall_average_Mom4_pos, overall_average_Mom5_pos, overall_average_Mom6_pos)), max(c(overall_average_MM_pos, overall_average_Mom1_pos, overall_average_Mom2_pos, overall_average_Mom3_pos, overall_average_Mom4_pos, overall_average_Mom5_pos, overall_average_Mom6_pos))))
lines(overall_average_Mom1_pos, type = "l", pch = 16, col = "red")
lines(overall_average_Mom2_pos, type = "l", pch = 16, col = "green")
lines(overall_average_Mom3_pos, type = "l", pch = 16, col = "yellow")
lines(overall_average_Mom4_pos, type = "l", pch = 16, col = "blue")
lines(overall_average_Mom5_pos, type = "l", pch = 16, col = "purple")
lines(overall_average_Mom6_pos, type = "l", pch = 16, col = "orange")
# Add legend
legend("bottomleft", legend = c("Market Maker", "Mom1", "Mom2", "Mom3", "Mom4", "Mom5", "Mom6"), col = c("black", "red", "green", "yellow", "blue", "purple", "orange"), lty = 1, cex = 0.8)

set11 (2 informed + 2 noisy informed + 2 noisy)
# Initialize matrices to store averages for each position
average_bid <- matrix(NA, nrow = 100, ncol = 10)
average_ask <- matrix(NA, nrow = 100, ncol = 10)
# Loop through each simulation (n)
for (n in 1:10) {
# Extract True values from the aggregated_results_4 dataframe
Bids_set11 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_11[n, 4])), ", ")
# Extract Expected values from the aggregated_results_4 dataframe
Asks_set11 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_11[n, 5])), ", ")
# Loop through each position (i)
for (i in 1:100) {
# Extract True and Expected values for the i-th position
Bids <- sapply(Bids_set11, function(x) as.numeric(x[i]))
Asks <- sapply(Asks_set11, function(x) as.numeric(x[i]))
# Calculate the average of True and Expected values for the i-th position
average_bid[i, n] <- mean(Bids, na.rm = TRUE)
average_ask[i, n] <- mean(Asks, na.rm = TRUE)
}
}
# Calculate the overall average for each position across all simulations
overall_average_bid <- rowMeans(average_bid, na.rm = TRUE)
overall_average_ask <- rowMeans(average_ask, na.rm = TRUE)
## True Value
# Initialize matrices to store averages for each position
average_true <- matrix(NA, nrow = 100, ncol = 10)
average_expected <- matrix(NA, nrow = 100, ncol = 10)
# Loop through each simulation (n)
for (n in 1:10) {
# Extract True values from the aggregated_results_4 dataframe
TrueValues_set11 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_11[n, 2])), ", ")
# Extract Expected values from the aggregated_results_4 dataframe
ExpectedValues_set11 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_11[n, 3])), ", ")
# Loop through each position (i)
for (i in 1:100) {
# Extract True and Expected values for the i-th position
True_values <- sapply(TrueValues_set11, function(x) as.numeric(x[i]))
Expected_values <- sapply(ExpectedValues_set11, function(x) as.numeric(x[i]))
# Calculate the average of True and Expected values for the i-th position
average_true[i, n] <- mean(True_values, na.rm = TRUE)
average_expected[i, n] <- mean(Expected_values, na.rm = TRUE)
}
}
# Calculate the overall average for each position across all simulations
overall_average_true <- rowMeans(average_true, na.rm = TRUE)
overall_average_expected <- rowMeans(average_expected, na.rm = TRUE)
# Plot the overall averages
#plot(overall_average_true, type = "l", pch = 16, col = "blue", main = "Overall Average of True vs Expected Values", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_true, overall_average_expected)), max(c(overall_average_true, overall_average_expected))))
#lines(overall_average_expected, type = "l", pch = 16, col = "red")
#legend("topright", legend = c("True Values", "Expected Values"), col = c("blue", "red"), lty = 1, cex = 0.8)
# Plot the overall averages
plot(overall_average_bid, type = "l", pch = 16, col = "blue", main = "Overall Average of Bids vs Asks & True vs Expected Values", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_bid, overall_average_ask, overall_average_true, overall_average_expected)), max(c(overall_average_bid, overall_average_ask, overall_average_true, overall_average_expected))))
lines(overall_average_ask, type = "l", pch = 16, col = "red")
lines(overall_average_true, type = "l", pch = 16, col = "green")
lines(overall_average_expected, type = "l", pch = 16, col = "purple")
legend("bottomleft", legend = c("Bids", "Asks", "True Value", "Expected Value"), col = c("blue", "red", "green", "purple"), lty = 1, cex = 0.8)

# Initialize matrices to store averages for each position
average_MM_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_Informed1_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_Informed2_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_NoisyInformed1_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_NoisyInformed2_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_Noisy1_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_Noisy2_pnl <- matrix(NA, nrow = 100, ncol = 10)
# Loop through each simulation (n)
for (n in 1:10) {
MM_pnl_set11 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_11[n, 6])), ", ")
Informed1_pnl_set11 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_11[n, 8])), ", ")
Informed2_pnl_set11 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_11[n, 10])), ", ")
NoisyInformed1_pnl_set11 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_11[n, 12])), ", ")
NoisyInformed2_pnl_set11 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_11[n, 14])), ", ")
Noisy1_pnl_set11 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_11[n, 16])), ", ")
Noisy2_pnl_set11 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_11[n, 18])), ", ")
# Loop through each position (i)
for (i in 1:100) {
# Extract True and Expected values for the i-th position
MM_pnl <- sapply(MM_pnl_set11, function(x) as.numeric(x[i]))
Informed1_pnl <- sapply(Informed1_pnl_set11, function(x) as.numeric(x[i]))
Informed2_pnl <- sapply(Informed2_pnl_set11, function(x) as.numeric(x[i]))
NoisyInformed1_pnl <- sapply(NoisyInformed1_pnl_set11, function(x) as.numeric(x[i]))
NoisyInformed1_pnl <- sapply(NoisyInformed2_pnl_set11, function(x) as.numeric(x[i]))
Noisy1_pnl <- sapply(Noisy1_pnl_set11, function(x) as.numeric(x[i]))
Noisy2_pnl <- sapply(Noisy2_pnl_set11, function(x) as.numeric(x[i]))
# Calculate the average of True and Expected values for the i-th position
average_MM_pnl[i, n] <- mean(MM_pnl, na.rm = TRUE)
average_Informed1_pnl[i, n] <- mean(Informed1_pnl, na.rm = TRUE)
average_Informed2_pnl[i, n] <- mean(Informed2_pnl, na.rm = TRUE)
average_NoisyInformed1_pnl[i, n] <- mean(NoisyInformed1_pnl, na.rm = TRUE)
average_NoisyInformed2_pnl[i, n] <- mean(NoisyInformed2_pnl, na.rm = TRUE)
average_Noisy1_pnl[i, n] <- mean(Noisy1_pnl, na.rm = TRUE)
average_Noisy2_pnl[i, n] <- mean(Noisy2_pnl, na.rm = TRUE)
}
}
# Calculate the overall average for each position across all simulations
overall_average_MM_pnl <- rowMeans(average_MM_pnl, na.rm = TRUE)
overall_average_Informed1_pnl <- rowMeans(average_Informed1_pnl, na.rm = TRUE)
overall_average_Informed2_pnl <- rowMeans(average_Informed2_pnl, na.rm = TRUE)
overall_average_NoisyInformed1_pnl <- rowMeans(average_NoisyInformed1_pnl, na.rm = TRUE)
overall_average_NoisyInformed2_pnl <- rowMeans(average_NoisyInformed2_pnl, na.rm = TRUE)
overall_average_Noisy1_pnl <- rowMeans(average_Noisy1_pnl, na.rm = TRUE)
overall_average_Noisy2_pnl <- rowMeans(average_Noisy2_pnl, na.rm = TRUE)
# Plot the overall averages
plot(overall_average_MM_pnl, type = "l", pch = 16, col = "black", main = "Overall Average PNL", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_MM_pnl, overall_average_Informed1_pnl, overall_average_Informed2_pnl, overall_average_NoisyInformed1_pnl, overall_average_NoisyInformed2_pnl, overall_average_Noisy1_pnl, overall_average_Noisy2_pnl)), max(c(overall_average_MM_pnl, overall_average_Informed1_pnl, overall_average_Informed2_pnl, overall_average_NoisyInformed1_pnl, overall_average_NoisyInformed2_pnl, overall_average_Noisy1_pnl, overall_average_Noisy2_pnl))))
lines(overall_average_Informed1_pnl, type = "l", pch = 16, col = "red")
lines(overall_average_Informed2_pnl, type = "l", pch = 16, col = "green")
lines(overall_average_NoisyInformed1_pnl, type = "l", pch = 16, col = "yellow")
lines(overall_average_NoisyInformed2_pnl, type = "l", pch = 16, col = "blue")
lines(overall_average_Noisy1_pnl, type = "l", pch = 16, col = "purple")
lines(overall_average_Noisy2_pnl, type = "l", pch = 16, col = "orange")
# Add legend
legend("bottomleft", legend = c("Market Maker", "Informed 1", "Informed 2", "Noisy Informed 1", "Noisy Informed 2", "Noisy 1", "Noisy 2"), col = c("black", "red", "green", "yellow", "blue", "purple", "orange"), lty = 1, cex = 0.8)

# Initialize matrices to store averages for each position
average_MM_pos <- matrix(NA, nrow = 100, ncol = 10)
average_Informed1_pos <- matrix(NA, nrow = 100, ncol = 10)
average_Informed2_pos <- matrix(NA, nrow = 100, ncol = 10)
average_NoisyInformed1_pos <- matrix(NA, nrow = 100, ncol = 10)
average_NoisyInformed2_pos <- matrix(NA, nrow = 100, ncol = 10)
average_Noisy1_pos <- matrix(NA, nrow = 100, ncol = 10)
average_Noisy2_pos <- matrix(NA, nrow = 100, ncol = 10)
# Loop through each simulation (n)
for (n in 1:10) {
MM_pos_set11 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_11[n, 7])), ", ")
Informed1_pos_set11 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_11[n, 9])), ", ")
Informed2_pos_set11 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_11[n, 11])), ", ")
NoisyInformed1_pos_set11 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_11[n, 13])), ", ")
NoisyInformed2_pos_set11 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_11[n, 15])), ", ")
Noisy1_pos_set11 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_11[n, 17])), ", ")
Noisy2_pos_set11 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_11[n, 19])), ", ")
# Loop through each position (i)
for (i in 1:100) {
# Extract True and Expected values for the i-th position
MM_pos <- sapply(MM_pnl_set11, function(x) as.numeric(x[i]))
Informed1_pos <- sapply(Informed1_pos_set11, function(x) as.numeric(x[i]))
Informed2_pos <- sapply(Informed2_pos_set11, function(x) as.numeric(x[i]))
NoisyInformed1_pos <- sapply(NoisyInformed1_pos_set11, function(x) as.numeric(x[i]))
NoisyInformed1_pos <- sapply(NoisyInformed2_pos_set11, function(x) as.numeric(x[i]))
Noisy1_pos <- sapply(Noisy1_pos_set11, function(x) as.numeric(x[i]))
Noisy2_pos <- sapply(Noisy2_pos_set11, function(x) as.numeric(x[i]))
# Calculate the average of True and Expected values for the i-th position
average_MM_pos[i, n] <- mean(MM_pos, na.rm = TRUE)
average_Informed1_pos[i, n] <- mean(Informed1_pos, na.rm = TRUE)
average_Informed2_pos[i, n] <- mean(Informed2_pos, na.rm = TRUE)
average_NoisyInformed1_pos[i, n] <- mean(NoisyInformed1_pos, na.rm = TRUE)
average_NoisyInformed2_pos[i, n] <- mean(NoisyInformed2_pos, na.rm = TRUE)
average_Noisy1_pos[i, n] <- mean(Noisy1_pos, na.rm = TRUE)
average_Noisy2_pos[i, n] <- mean(Noisy2_pos, na.rm = TRUE)
}
}
# Calculate the overall average for each position across all simulations
overall_average_MM_pos <- rowMeans(average_MM_pos, na.rm = TRUE)
overall_average_Informed1_pos <- rowMeans(average_Informed1_pos, na.rm = TRUE)
overall_average_Informed2_pos <- rowMeans(average_Informed2_pos, na.rm = TRUE)
overall_average_NoisyInformed1_pos <- rowMeans(average_NoisyInformed1_pos, na.rm = TRUE)
overall_average_NoisyInformed2_pos <- rowMeans(average_NoisyInformed2_pos, na.rm = TRUE)
overall_average_Noisy1_pos <- rowMeans(average_Noisy1_pos, na.rm = TRUE)
overall_average_Noisy2_pos <- rowMeans(average_Noisy2_pos, na.rm = TRUE)
# Plot the overall averages
plot(overall_average_MM_pos, type = "l", pch = 16, col = "black", main = "Overall Average Position", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_MM_pos, overall_average_Informed1_pos, overall_average_Informed2_pos, overall_average_NoisyInformed1_pos, overall_average_NoisyInformed2_pos, overall_average_Noisy1_pos, overall_average_Noisy2_pos)), max(c(overall_average_MM_pos, overall_average_Informed1_pos, overall_average_Informed2_pos, overall_average_NoisyInformed1_pos, overall_average_NoisyInformed2_pos, overall_average_Noisy1_pos, overall_average_Noisy2_pos))))
lines(overall_average_Informed1_pos, type = "l", pch = 16, col = "red")
lines(overall_average_Informed2_pos, type = "l", pch = 16, col = "green")
lines(overall_average_NoisyInformed1_pos, type = "l", pch = 16, col = "yellow")
lines(overall_average_NoisyInformed2_pos, type = "l", pch = 16, col = "blue")
lines(overall_average_Noisy1_pos, type = "l", pch = 16, col = "purple")
lines(overall_average_Noisy2_pos, type = "l", pch = 16, col = "orange")
# Add legend
legend("bottomleft", legend = c("Market Maker", "Informed 1", "Informed 2", "Noisy Informed 1", "Noisy Informed 2", "Noisy 1", "Noisy 2"), col = c("black", "red", "green", "yellow", "blue", "purple", "orange"), lty = 1, cex = 0.8)

set12 (6 Stochastic Noisy)
# Initialize matrices to store averages for each position
average_bid <- matrix(NA, nrow = 100, ncol = 10)
average_ask <- matrix(NA, nrow = 100, ncol = 10)
# Loop through each simulation (n)
for (n in 1:10) {
# Extract True values from the aggregated_results_4 dataframe
Bids_set12 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_12[n, 4])), ", ")
# Extract Expected values from the aggregated_results_4 dataframe
Asks_set12 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_12[n, 5])), ", ")
# Loop through each position (i)
for (i in 1:100) {
# Extract True and Expected values for the i-th position
Bids <- sapply(Bids_set12, function(x) as.numeric(x[i]))
Asks <- sapply(Asks_set12, function(x) as.numeric(x[i]))
# Calculate the average of True and Expected values for the i-th position
average_bid[i, n] <- mean(Bids, na.rm = TRUE)
average_ask[i, n] <- mean(Asks, na.rm = TRUE)
}
}
# Calculate the overall average for each position across all simulations
overall_average_bid <- rowMeans(average_bid, na.rm = TRUE)
overall_average_ask <- rowMeans(average_ask, na.rm = TRUE)
## True Value
# Initialize matrices to store averages for each position
average_true <- matrix(NA, nrow = 100, ncol = 10)
average_expected <- matrix(NA, nrow = 100, ncol = 10)
# Loop through each simulation (n)
for (n in 1:10) {
# Extract True values from the aggregated_results_4 dataframe
TrueValues_set12 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_12[n, 2])), ", ")
# Extract Expected values from the aggregated_results_4 dataframe
ExpectedValues_set12 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_12[n, 3])), ", ")
# Loop through each position (i)
for (i in 1:100) {
# Extract True and Expected values for the i-th position
True_values <- sapply(TrueValues_set12, function(x) as.numeric(x[i]))
Expected_values <- sapply(ExpectedValues_set12, function(x) as.numeric(x[i]))
# Calculate the average of True and Expected values for the i-th position
average_true[i, n] <- mean(True_values, na.rm = TRUE)
average_expected[i, n] <- mean(Expected_values, na.rm = TRUE)
}
}
# Calculate the overall average for each position across all simulations
overall_average_true <- rowMeans(average_true, na.rm = TRUE)
overall_average_expected <- rowMeans(average_expected, na.rm = TRUE)
# Plot the overall averages
#plot(overall_average_true, type = "l", pch = 16, col = "blue", main = "Overall Average of True vs Expected Values", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_true, overall_average_expected)), max(c(overall_average_true, overall_average_expected))))
#lines(overall_average_expected, type = "l", pch = 16, col = "red")
#legend("topright", legend = c("True Values", "Expected Values"), col = c("blue", "red"), lty = 1, cex = 0.8)
# Plot the overall averages
plot(overall_average_bid, type = "l", pch = 16, col = "blue", main = "Overall Average of Bids vs Asks & True vs Expected Values", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_bid, overall_average_ask, overall_average_true, overall_average_expected)), max(c(overall_average_bid, overall_average_ask, overall_average_true, overall_average_expected))))
lines(overall_average_ask, type = "l", pch = 16, col = "red")
lines(overall_average_true, type = "l", pch = 16, col = "green")
lines(overall_average_expected, type = "l", pch = 16, col = "purple")
legend("bottomleft", legend = c("Bids", "Asks", "True Value", "Expected Value"), col = c("blue", "red", "green", "purple"), lty = 1, cex = 0.8)

# Initialize matrices to store averages for each position
average_MM_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_StochNoisy1_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_StochNoisy2_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_StochNoisy3_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_StochNoisy4_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_StochNoisy5_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_StochNoisy6_pnl <- matrix(NA, nrow = 100, ncol = 10)
# Loop through each simulation (n)
for (n in 1:10) {
MM_pnl_set12 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_12[n, 6])), ", ")
StochNoisy1_pnl_set12 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_12[n, 8])), ", ")
StochNoisy2_pnl_set12 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_12[n, 10])), ", ")
StochNoisy3_pnl_set12 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_12[n, 12])), ", ")
StochNoisy4_pnl_set12 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_12[n, 14])), ", ")
StochNoisy5_pnl_set12 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_12[n, 16])), ", ")
StochNoisy6_pnl_set12 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_12[n, 18])), ", ")
# Loop through each position (i)
for (i in 1:100) {
# Extract True and Expected values for the i-th position
MM_pnl <- sapply(MM_pnl_set12, function(x) as.numeric(x[i]))
StochNoisy1_pnl <- sapply(StochNoisy1_pnl_set12, function(x) as.numeric(x[i]))
StochNoisy2_pnl <- sapply(StochNoisy2_pnl_set12, function(x) as.numeric(x[i]))
StochNoisy3_pnl <- sapply(StochNoisy3_pnl_set12, function(x) as.numeric(x[i]))
StochNoisy4_pnl <- sapply(StochNoisy4_pnl_set12, function(x) as.numeric(x[i]))
StochNoisy5_pnl <- sapply(StochNoisy5_pnl_set12, function(x) as.numeric(x[i]))
StochNoisy6_pnl <- sapply(StochNoisy6_pnl_set12, function(x) as.numeric(x[i]))
# Calculate the average of True and Expected values for the i-th position
average_MM_pnl[i, n] <- mean(MM_pnl, na.rm = TRUE)
average_StochNoisy1_pnl[i, n] <- mean(StochNoisy1_pnl, na.rm = TRUE)
average_StochNoisy2_pnl[i, n] <- mean(StochNoisy2_pnl, na.rm = TRUE)
average_StochNoisy3_pnl[i, n] <- mean(StochNoisy3_pnl, na.rm = TRUE)
average_StochNoisy4_pnl[i, n] <- mean(StochNoisy4_pnl, na.rm = TRUE)
average_StochNoisy5_pnl[i, n] <- mean(StochNoisy5_pnl, na.rm = TRUE)
average_StochNoisy6_pnl[i, n] <- mean(StochNoisy6_pnl, na.rm = TRUE)
}
}
# Calculate the overall average for each position across all simulations
overall_average_MM_pnl <- rowMeans(average_MM_pnl, na.rm = TRUE)
overall_average_StochNoisy1_pnl <- rowMeans(average_StochNoisy1_pnl, na.rm = TRUE)
overall_average_StochNoisy2_pnl <- rowMeans(average_StochNoisy2_pnl, na.rm = TRUE)
overall_average_StochNoisy3_pnl <- rowMeans(average_StochNoisy3_pnl, na.rm = TRUE)
overall_average_StochNoisy4_pnl <- rowMeans(average_StochNoisy4_pnl, na.rm = TRUE)
overall_average_StochNoisy5_pnl <- rowMeans(average_StochNoisy5_pnl, na.rm = TRUE)
overall_average_StochNoisy6_pnl <- rowMeans(average_StochNoisy6_pnl, na.rm = TRUE)
# Plot the overall averages
plot(overall_average_MM_pnl, type = "l", pch = 16, col = "black", main = "Overall Average PNL", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_MM_pnl, overall_average_StochNoisy1_pnl, overall_average_StochNoisy2_pnl, overall_average_StochNoisy3_pnl, overall_average_StochNoisy4_pnl, overall_average_StochNoisy5_pnl, overall_average_StochNoisy6_pnl)), max(c(overall_average_MM_pnl, overall_average_StochNoisy1_pnl, overall_average_StochNoisy2_pnl, overall_average_StochNoisy3_pnl, overall_average_StochNoisy4_pnl, overall_average_StochNoisy5_pnl, overall_average_StochNoisy6_pnl))))
lines(overall_average_StochNoisy1_pnl, type = "l", pch = 16, col = "red")
lines(overall_average_StochNoisy2_pnl, type = "l", pch = 16, col = "green")
lines(overall_average_StochNoisy3_pnl, type = "l", pch = 16, col = "yellow")
lines(overall_average_StochNoisy4_pnl, type = "l", pch = 16, col = "blue")
lines(overall_average_StochNoisy5_pnl, type = "l", pch = 16, col = "purple")
lines(overall_average_StochNoisy6_pnl, type = "l", pch = 16, col = "orange")
# Add legend
legend("topleft", legend = c("Market Maker", "Stochactic Noisy 1", "Stochactic Noisy 2", "Stochactic Noisy 3", "Stochactic Noisy 4", "Stochactic Noisy 5", "Stochactic Noisy 6"), col = c("black", "red", "green", "yellow", "blue", "purple", "orange"), lty = 1, cex = 0.8)

# Initialize matrices to store averages for each position
average_MM_pos <- matrix(NA, nrow = 100, ncol = 10)
average_StochNoisy1_pos <- matrix(NA, nrow = 100, ncol = 10)
average_StochNoisy2_pos <- matrix(NA, nrow = 100, ncol = 10)
average_StochNoisy3_pos <- matrix(NA, nrow = 100, ncol = 10)
average_StochNoisy4_pos <- matrix(NA, nrow = 100, ncol = 10)
average_StochNoisy5_pos <- matrix(NA, nrow = 100, ncol = 10)
average_StochNoisy6_pos <- matrix(NA, nrow = 100, ncol = 10)
# Loop through each simulation (n)
for (n in 1:10) {
MM_pos_set12 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_12[n, 7])), ", ")
StochNoisy1_pos_set12 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_12[n, 9])), ", ")
StochNoisy2_pos_set12 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_12[n, 11])), ", ")
StochNoisy3_pos_set12 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_12[n, 13])), ", ")
StochNoisy4_pos_set12 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_12[n, 15])), ", ")
StochNoisy5_pos_set12 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_12[n, 17])), ", ")
StochNoisy6_pos_set12 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_12[n, 19])), ", ")
# Loop through each position (i)
for (i in 1:100) {
# Extract True and Expected values for the i-th position
MM_pos <- sapply(MM_pos_set12, function(x) as.numeric(x[i]))
StochNoisy1_pos <- sapply(StochNoisy1_pos_set12, function(x) as.numeric(x[i]))
StochNoisy2_pos <- sapply(StochNoisy2_pos_set12, function(x) as.numeric(x[i]))
StochNoisy3_pos <- sapply(StochNoisy3_pos_set12, function(x) as.numeric(x[i]))
StochNoisy4_pos <- sapply(StochNoisy4_pos_set12, function(x) as.numeric(x[i]))
StochNoisy5_pos <- sapply(StochNoisy5_pos_set12, function(x) as.numeric(x[i]))
StochNoisy6_pos <- sapply(StochNoisy6_pos_set12, function(x) as.numeric(x[i]))
# Calculate the average of True and Expected values for the i-th position
average_MM_pos[i, n] <- mean(MM_pos, na.rm = TRUE)
average_StochNoisy1_pos[i, n] <- mean(StochNoisy1_pos, na.rm = TRUE)
average_StochNoisy2_pos[i, n] <- mean(StochNoisy2_pos, na.rm = TRUE)
average_StochNoisy3_pos[i, n] <- mean(StochNoisy3_pos, na.rm = TRUE)
average_StochNoisy4_pos[i, n] <- mean(StochNoisy4_pos, na.rm = TRUE)
average_StochNoisy5_pos[i, n] <- mean(StochNoisy5_pos, na.rm = TRUE)
average_StochNoisy6_pos[i, n] <- mean(StochNoisy6_pos, na.rm = TRUE)
}
}
# Calculate the overall average for each position across all simulations
overall_average_MM_pos <- rowMeans(average_MM_pos, na.rm = TRUE)
overall_average_StochNoisy1_pos <- rowMeans(average_StochNoisy1_pos, na.rm = TRUE)
overall_average_StochNoisy2_pos <- rowMeans(average_StochNoisy2_pos, na.rm = TRUE)
overall_average_StochNoisy3_pos <- rowMeans(average_StochNoisy3_pos, na.rm = TRUE)
overall_average_StochNoisy4_pos <- rowMeans(average_StochNoisy4_pos, na.rm = TRUE)
overall_average_StochNoisy5_pos <- rowMeans(average_StochNoisy5_pos, na.rm = TRUE)
overall_average_StochNoisy6_pos <- rowMeans(average_StochNoisy6_pos, na.rm = TRUE)
# Plot the overall averages
plot(overall_average_MM_pos, type = "l", pch = 16, col = "black", main = "Overall Average Position", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_MM_pos, overall_average_StochNoisy1_pos, overall_average_StochNoisy2_pos, overall_average_StochNoisy3_pos, overall_average_StochNoisy4_pos, overall_average_StochNoisy5_pos, overall_average_StochNoisy6_pos)), max(c(overall_average_MM_pos, overall_average_StochNoisy1_pos, overall_average_StochNoisy2_pos, overall_average_StochNoisy3_pos, overall_average_StochNoisy4_pos, overall_average_StochNoisy5_pos, overall_average_StochNoisy6_pos))))
lines(overall_average_StochNoisy1_pos, type = "l", pch = 16, col = "red")
lines(overall_average_StochNoisy2_pos, type = "l", pch = 16, col = "green")
lines(overall_average_StochNoisy3_pos, type = "l", pch = 16, col = "yellow")
lines(overall_average_StochNoisy4_pos, type = "l", pch = 16, col = "blue")
lines(overall_average_StochNoisy5_pos, type = "l", pch = 16, col = "purple")
lines(overall_average_StochNoisy6_pos, type = "l", pch = 16, col = "orange")
# Add legend
legend("topleft", legend = c("Market Maker", "Stochastic Noisy 1", "Stochastic Noisy 2", "Stochastic Noisy 3", "Stochastic Noisy 4", "Stochastic Noisy 5", "Stochastic Noisy 6"), col = c("black", "red", "green", "yellow", "blue", "purple", "orange"), lty = 1, cex = 0.8)

set13 (6 noisy informed)
# Initialize matrices to store averages for each position
average_bid <- matrix(NA, nrow = 100, ncol = 10)
average_ask <- matrix(NA, nrow = 100, ncol = 10)
# Loop through each simulation (n)
for (n in 1:10) {
# Extract True values from the aggregated_results_4 dataframe
Bids_set13 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_13[n, 4])), ", ")
# Extract Expected values from the aggregated_results_4 dataframe
Asks_set13 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_13[n, 5])), ", ")
# Loop through each position (i)
for (i in 1:100) {
# Extract True and Expected values for the i-th position
Bids <- sapply(Bids_set13, function(x) as.numeric(x[i]))
Asks <- sapply(Asks_set13, function(x) as.numeric(x[i]))
# Calculate the average of True and Expected values for the i-th position
average_bid[i, n] <- mean(Bids, na.rm = TRUE)
average_ask[i, n] <- mean(Asks, na.rm = TRUE)
}
}
# Calculate the overall average for each position across all simulations
overall_average_bid <- rowMeans(average_bid, na.rm = TRUE)
overall_average_ask <- rowMeans(average_ask, na.rm = TRUE)
## True Value
# Initialize matrices to store averages for each position
average_true <- matrix(NA, nrow = 100, ncol = 10)
average_expected <- matrix(NA, nrow = 100, ncol = 10)
# Loop through each simulation (n)
for (n in 1:10) {
# Extract True values from the aggregated_results_4 dataframe
TrueValues_set13 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_13[n, 2])), ", ")
# Extract Expected values from the aggregated_results_4 dataframe
ExpectedValues_set13 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_13[n, 3])), ", ")
# Loop through each position (i)
for (i in 1:100) {
# Extract True and Expected values for the i-th position
True_values <- sapply(TrueValues_set13, function(x) as.numeric(x[i]))
Expected_values <- sapply(ExpectedValues_set13, function(x) as.numeric(x[i]))
# Calculate the average of True and Expected values for the i-th position
average_true[i, n] <- mean(True_values, na.rm = TRUE)
average_expected[i, n] <- mean(Expected_values, na.rm = TRUE)
}
}
# Calculate the overall average for each position across all simulations
overall_average_true <- rowMeans(average_true, na.rm = TRUE)
overall_average_expected <- rowMeans(average_expected, na.rm = TRUE)
# Plot the overall averages
#plot(overall_average_true, type = "l", pch = 16, col = "blue", main = "Overall Average of True vs Expected Values", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_true, overall_average_expected)), max(c(overall_average_true, overall_average_expected))))
#lines(overall_average_expected, type = "l", pch = 16, col = "red")
#legend("topright", legend = c("True Values", "Expected Values"), col = c("blue", "red"), lty = 1, cex = 0.8)
# Plot the overall averages
plot(overall_average_bid, type = "l", pch = 16, col = "blue", main = "Overall Average of Bids vs Asks & True vs Expected Values", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_bid, overall_average_ask, overall_average_true, overall_average_expected)), max(c(overall_average_bid, overall_average_ask, overall_average_true, overall_average_expected))))
lines(overall_average_ask, type = "l", pch = 16, col = "red")
lines(overall_average_true, type = "l", pch = 16, col = "green")
lines(overall_average_expected, type = "l", pch = 16, col = "purple")
legend("bottomleft", legend = c("Bids", "Asks", "True Value", "Expected Value"), col = c("blue", "red", "green", "purple"), lty = 1, cex = 0.8)

# Initialize matrices to store averages for each position
average_MM_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_NoisyInformed1_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_NoisyInformed2_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_NoisyInformed3_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_NoisyInformed4_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_NoisyInformed5_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_NoisyInformed6_pnl <- matrix(NA, nrow = 100, ncol = 10)
# Loop through each simulation (n)
for (n in 1:10) {
MM_pnl_set13 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_13[n, 6])), ", ")
NoisyInformed1_pnl_set13 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_13[n, 8])), ", ")
NoisyInformed2_pnl_set13 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_13[n, 10])), ", ")
NoisyInformed3_pnl_set13 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_13[n, 12])), ", ")
NoisyInformed4_pnl_set13 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_13[n, 14])), ", ")
NoisyInformed5_pnl_set13 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_13[n, 16])), ", ")
NoisyInformed6_pnl_set13 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_13[n, 18])), ", ")
# Loop through each position (i)
for (i in 1:100) {
# Extract True and Expected values for the i-th position
MM_pnl <- sapply(MM_pnl_set13, function(x) as.numeric(x[i]))
NoisyInformed1_pnl <- sapply(NoisyInformed1_pnl_set13, function(x) as.numeric(x[i]))
NoisyInformed2_pnl <- sapply(NoisyInformed2_pnl_set13, function(x) as.numeric(x[i]))
NoisyInformed3_pnl <- sapply(NoisyInformed3_pnl_set13, function(x) as.numeric(x[i]))
NoisyInformed4_pnl <- sapply(NoisyInformed4_pnl_set13, function(x) as.numeric(x[i]))
NoisyInformed5_pnl <- sapply(NoisyInformed5_pnl_set13, function(x) as.numeric(x[i]))
NoisyInformed6_pnl <- sapply(NoisyInformed6_pnl_set13, function(x) as.numeric(x[i]))
# Calculate the average of True and Expected values for the i-th position
average_MM_pnl[i, n] <- mean(MM_pnl, na.rm = TRUE)
average_NoisyInformed1_pnl[i, n] <- mean(NoisyInformed1_pnl, na.rm = TRUE)
average_NoisyInformed2_pnl[i, n] <- mean(NoisyInformed2_pnl, na.rm = TRUE)
average_NoisyInformed3_pnl[i, n] <- mean(NoisyInformed3_pnl, na.rm = TRUE)
average_NoisyInformed4_pnl[i, n] <- mean(NoisyInformed4_pnl, na.rm = TRUE)
average_NoisyInformed5_pnl[i, n] <- mean(NoisyInformed5_pnl, na.rm = TRUE)
average_NoisyInformed6_pnl[i, n] <- mean(NoisyInformed6_pnl, na.rm = TRUE)
}
}
# Calculate the overall average for each position across all simulations
overall_average_MM_pnl <- rowMeans(average_MM_pnl, na.rm = TRUE)
overall_average_NoisyInformed1_pnl <- rowMeans(average_NoisyInformed1_pnl, na.rm = TRUE)
overall_average_NoisyInformed2_pnl <- rowMeans(average_NoisyInformed2_pnl, na.rm = TRUE)
overall_average_NoisyInformed3_pnl <- rowMeans(average_NoisyInformed3_pnl, na.rm = TRUE)
overall_average_NoisyInformed4_pnl <- rowMeans(average_NoisyInformed4_pnl, na.rm = TRUE)
overall_average_NoisyInformed5_pnl <- rowMeans(average_NoisyInformed5_pnl, na.rm = TRUE)
overall_average_NoisyInformed6_pnl <- rowMeans(average_NoisyInformed6_pnl, na.rm = TRUE)
# Plot the overall averages
plot(overall_average_MM_pnl, type = "l", pch = 16, col = "black", main = "Overall Average PNL", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_MM_pnl, overall_average_NoisyInformed1_pnl, overall_average_NoisyInformed2_pnl, overall_average_NoisyInformed3_pnl, overall_average_NoisyInformed4_pnl, overall_average_NoisyInformed5_pnl, overall_average_NoisyInformed6_pnl)), max(c(overall_average_MM_pnl, overall_average_NoisyInformed1_pnl, overall_average_NoisyInformed2_pnl, overall_average_NoisyInformed3_pnl, overall_average_NoisyInformed4_pnl, overall_average_NoisyInformed5_pnl, overall_average_NoisyInformed6_pnl))))
lines(overall_average_NoisyInformed1_pnl, type = "l", pch = 16, col = "red")
lines(overall_average_NoisyInformed2_pnl, type = "l", pch = 16, col = "green")
lines(overall_average_NoisyInformed3_pnl, type = "l", pch = 16, col = "yellow")
lines(overall_average_NoisyInformed4_pnl, type = "l", pch = 16, col = "blue")
lines(overall_average_NoisyInformed5_pnl, type = "l", pch = 16, col = "purple")
lines(overall_average_NoisyInformed6_pnl, type = "l", pch = 16, col = "orange")
# Add legend
legend("bottomleft", legend = c("Market Maker", "Noisy Informed 1", "Noisy Informed 2", "Noisy Informed 3", "Noisy Informed 4", "Noisy Informed 5", "Noisy Informed 6"), col = c("black", "red", "green", "yellow", "blue", "purple", "orange"), lty = 1, cex = 0.8)

# Initialize matrices to store averages for each position
average_MM_pos <- matrix(NA, nrow = 100, ncol = 10)
average_NoisyInformed1_pos <- matrix(NA, nrow = 100, ncol = 10)
average_NoisyInformed2_pos <- matrix(NA, nrow = 100, ncol = 10)
average_NoisyInformed3_pos <- matrix(NA, nrow = 100, ncol = 10)
average_NoisyInformed4_pos <- matrix(NA, nrow = 100, ncol = 10)
average_NoisyInformed5_pos <- matrix(NA, nrow = 100, ncol = 10)
average_NoisyInformed6_pos <- matrix(NA, nrow = 100, ncol = 10)
# Loop through each simulation (n)
for (n in 1:10) {
MM_pos_set13 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_13[n, 7])), ", ")
NoisyInformed1_pos_set13 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_13[n, 9])), ", ")
NoisyInformed2_pos_set13 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_13[n, 11])), ", ")
NoisyInformed3_pos_set13 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_13[n, 13])), ", ")
NoisyInformed4_pos_set13 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_13[n, 15])), ", ")
NoisyInformed5_pos_set13 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_13[n, 17])), ", ")
NoisyInformed6_pos_set13 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_13[n, 19])), ", ")
# Loop through each position (i)
for (i in 1:100) {
# Extract True and Expected values for the i-th position
MM_pos <- sapply(MM_pos_set13, function(x) as.numeric(x[i]))
NoisyInformed1_pos <- sapply(NoisyInformed1_pos_set13, function(x) as.numeric(x[i]))
NoisyInformed2_pos <- sapply(NoisyInformed2_pos_set13, function(x) as.numeric(x[i]))
NoisyInformed3_pos <- sapply(NoisyInformed3_pos_set13, function(x) as.numeric(x[i]))
NoisyInformed4_pos <- sapply(NoisyInformed4_pos_set13, function(x) as.numeric(x[i]))
NoisyInformed5_pos <- sapply(NoisyInformed5_pos_set13, function(x) as.numeric(x[i]))
NoisyInformed6_pos <- sapply(NoisyInformed6_pos_set13, function(x) as.numeric(x[i]))
# Calculate the average of True and Expected values for the i-th position
average_MM_pos[i, n] <- mean(MM_pos, na.rm = TRUE)
average_NoisyInformed1_pos[i, n] <- mean(NoisyInformed1_pos, na.rm = TRUE)
average_NoisyInformed2_pos[i, n] <- mean(NoisyInformed2_pos, na.rm = TRUE)
average_NoisyInformed3_pos[i, n] <- mean(NoisyInformed3_pos, na.rm = TRUE)
average_NoisyInformed4_pos[i, n] <- mean(NoisyInformed4_pos, na.rm = TRUE)
average_NoisyInformed5_pos[i, n] <- mean(NoisyInformed5_pos, na.rm = TRUE)
average_NoisyInformed6_pos[i, n] <- mean(NoisyInformed6_pos, na.rm = TRUE)
}
}
# Calculate the overall average for each position across all simulations
overall_average_MM_pos <- rowMeans(average_MM_pos, na.rm = TRUE)
overall_average_NoisyInformed1_pos <- rowMeans(average_NoisyInformed1_pos, na.rm = TRUE)
overall_average_NoisyInformed2_pos <- rowMeans(average_NoisyInformed2_pos, na.rm = TRUE)
overall_average_NoisyInformed3_pos <- rowMeans(average_NoisyInformed3_pos, na.rm = TRUE)
overall_average_NoisyInformed4_pos <- rowMeans(average_NoisyInformed4_pos, na.rm = TRUE)
overall_average_NoisyInformed5_pos <- rowMeans(average_NoisyInformed5_pos, na.rm = TRUE)
overall_average_NoisyInformed6_pos <- rowMeans(average_NoisyInformed6_pos, na.rm = TRUE)
# Plot the overall averages
plot(overall_average_MM_pos, type = "l", pch = 16, col = "black", main = "Overall Average Position", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_MM_pos, overall_average_StochNoisy1_pos, overall_average_NoisyInformed2_pos, overall_average_NoisyInformed3_pos, overall_average_NoisyInformed4_pos, overall_average_NoisyInformed5_pos, overall_average_NoisyInformed6_pos)), max(c(overall_average_MM_pos, overall_average_NoisyInformed1_pos, overall_average_NoisyInformed2_pos, overall_average_NoisyInformed3_pos, overall_average_NoisyInformed4_pos, overall_average_NoisyInformed5_pos, overall_average_NoisyInformed6_pos))))
lines(overall_average_NoisyInformed1_pos, type = "l", pch = 16, col = "red")
lines(overall_average_NoisyInformed2_pos, type = "l", pch = 16, col = "green")
lines(overall_average_NoisyInformed3_pos, type = "l", pch = 16, col = "yellow")
lines(overall_average_NoisyInformed4_pos, type = "l", pch = 16, col = "blue")
lines(overall_average_NoisyInformed5_pos, type = "l", pch = 16, col = "purple")
lines(overall_average_NoisyInformed6_pos, type = "l", pch = 16, col = "orange")
# Add legend
legend("topleft", legend = c("Market Maker", "Noisy Informed 1", "Noisy Informed 2", "Noisy Informed 3", "Noisy Informed 4", "Noisy Informed 5", "Noisy Informed 6"), col = c("black", "red", "green", "yellow", "blue", "purple", "orange"), lty = 1, cex = 0.8)

set14 (1 informed + 2 noisy informed + 2 noisy + 1 mean
reversion)
# Initialize matrices to store averages for each position
average_bid <- matrix(NA, nrow = 100, ncol = 10)
average_ask <- matrix(NA, nrow = 100, ncol = 10)
# Loop through each simulation (n)
for (n in 1:10) {
# Extract True values from the aggregated_results_4 dataframe
Bids_set14 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_14[n, 4])), ", ")
# Extract Expected values from the aggregated_results_4 dataframe
Asks_set14 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_14[n, 5])), ", ")
# Loop through each position (i)
for (i in 1:100) {
# Extract True and Expected values for the i-th position
Bids <- sapply(Bids_set14, function(x) as.numeric(x[i]))
Asks <- sapply(Asks_set14, function(x) as.numeric(x[i]))
# Calculate the average of True and Expected values for the i-th position
average_bid[i, n] <- mean(Bids, na.rm = TRUE)
average_ask[i, n] <- mean(Asks, na.rm = TRUE)
}
}
# Calculate the overall average for each position across all simulations
overall_average_bid <- rowMeans(average_bid, na.rm = TRUE)
overall_average_ask <- rowMeans(average_ask, na.rm = TRUE)
## True Value
# Initialize matrices to store averages for each position
average_true <- matrix(NA, nrow = 100, ncol = 10)
average_expected <- matrix(NA, nrow = 100, ncol = 10)
# Loop through each simulation (n)
for (n in 1:10) {
# Extract True values from the aggregated_results_4 dataframe
TrueValues_set14 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_14[n, 2])), ", ")
# Extract Expected values from the aggregated_results_4 dataframe
ExpectedValues_set14 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_14[n, 3])), ", ")
# Loop through each position (i)
for (i in 1:100) {
# Extract True and Expected values for the i-th position
True_values <- sapply(TrueValues_set14, function(x) as.numeric(x[i]))
Expected_values <- sapply(ExpectedValues_set14, function(x) as.numeric(x[i]))
# Calculate the average of True and Expected values for the i-th position
average_true[i, n] <- mean(True_values, na.rm = TRUE)
average_expected[i, n] <- mean(Expected_values, na.rm = TRUE)
}
}
# Calculate the overall average for each position across all simulations
overall_average_true <- rowMeans(average_true, na.rm = TRUE)
overall_average_expected <- rowMeans(average_expected, na.rm = TRUE)
# Plot the overall averages
#plot(overall_average_true, type = "l", pch = 16, col = "blue", main = "Overall Average of True vs Expected Values", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_true, overall_average_expected)), max(c(overall_average_true, overall_average_expected))))
#lines(overall_average_expected, type = "l", pch = 16, col = "red")
#legend("topright", legend = c("True Values", "Expected Values"), col = c("blue", "red"), lty = 1, cex = 0.8)
# Plot the overall averages
plot(overall_average_bid, type = "l", pch = 16, col = "blue", main = "Overall Average of Bids vs Asks & True vs Expected Values", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_bid, overall_average_ask, overall_average_true, overall_average_expected)), max(c(overall_average_bid, overall_average_ask, overall_average_true, overall_average_expected))))
lines(overall_average_ask, type = "l", pch = 16, col = "red")
lines(overall_average_true, type = "l", pch = 16, col = "green")
lines(overall_average_expected, type = "l", pch = 16, col = "purple")
legend("bottomleft", legend = c("Bids", "Asks", "True Value", "Expected Value"), col = c("blue", "red", "green", "purple"), lty = 1, cex = 0.8)

# Initialize matrices to store averages for each position
average_MM_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_Informed_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_NoisyInformed1_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_NoisyInformed2_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_Noisy1_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_Noisy2_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_mr_pnl <- matrix(NA, nrow = 100, ncol = 10)
# Loop through each simulation (n)
for (n in 1:10) {
MM_pnl_set14 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_14[n, 6])), ", ")
Informed_pnl_set14 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_14[n, 8])), ", ")
NoisyInformed1_pnl_set14 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_14[n, 10])), ", ")
NoisyInformed2_pnl_set14 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_14[n, 12])), ", ")
Noisy1_pnl_set14 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_14[n, 14])), ", ")
Noisy2_pnl_set14 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_14[n, 16])), ", ")
mr_pnl_set14 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_14[n, 18])), ", ")
# Loop through each position (i)
for (i in 1:100) {
# Extract True and Expected values for the i-th position
MM_pnl <- sapply(MM_pnl_set14, function(x) as.numeric(x[i]))
Informed_pnl <- sapply(Informed_pnl_set14, function(x) as.numeric(x[i]))
NoisyInformed1_pnl <- sapply(NoisyInformed1_pnl_set14, function(x) as.numeric(x[i]))
NoisyInformed2_pnl <- sapply(NoisyInformed2_pnl_set14, function(x) as.numeric(x[i]))
Noisy1_pnl <- sapply(Noisy1_pnl_set14, function(x) as.numeric(x[i]))
Noisy2_pnl <- sapply(Noisy2_pnl_set14, function(x) as.numeric(x[i]))
mr_pnl <- sapply(mr_pnl_set14, function(x) as.numeric(x[i]))
# Calculate the average of True and Expected values for the i-th position
average_MM_pnl[i, n] <- mean(MM_pnl, na.rm = TRUE)
average_Informed_pnl[i, n] <- mean(Informed_pnl, na.rm = TRUE)
average_NoisyInformed1_pnl[i, n] <- mean(NoisyInformed1_pnl, na.rm = TRUE)
average_NoisyInformed2_pnl[i, n] <- mean(NoisyInformed2_pnl, na.rm = TRUE)
average_Noisy1_pnl[i, n] <- mean(Noisy1_pnl, na.rm = TRUE)
average_Noisy2_pnl[i, n] <- mean(Noisy2_pnl, na.rm = TRUE)
average_mr_pnl[i, n] <- mean(mr_pnl, na.rm = TRUE)
}
}
# Calculate the overall average for each position across all simulations
overall_average_MM_pnl <- rowMeans(average_MM_pnl, na.rm = TRUE)
overall_average_Informed_pnl <- rowMeans(average_Informed_pnl, na.rm = TRUE)
overall_average_NoisyInformed1_pnl <- rowMeans(average_NoisyInformed1_pnl, na.rm = TRUE)
overall_average_NoisyInformed2_pnl <- rowMeans(average_NoisyInformed2_pnl, na.rm = TRUE)
overall_average_Noisy1_pnl <- rowMeans(average_Noisy1_pnl, na.rm = TRUE)
overall_average_Noisy2_pnl <- rowMeans(average_Noisy2_pnl, na.rm = TRUE)
overall_average_mr_pnl <- rowMeans(average_mr_pnl, na.rm = TRUE)
# Plot the overall averages
plot(overall_average_MM_pnl, type = "l", pch = 16, col = "black", main = "Overall Average PNL", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_MM_pnl, overall_average_Informed_pnl, overall_average_NoisyInformed1_pnl, overall_average_NoisyInformed2_pnl, overall_average_Noisy1_pnl, overall_average_Noisy2_pnl, overall_average_mr_pnl)), max(c(overall_average_MM_pnl, overall_average_Informed_pnl, overall_average_NoisyInformed1_pnl, overall_average_NoisyInformed2_pnl, overall_average_Noisy1_pnl, overall_average_Noisy2_pnl, overall_average_mr_pnl))))
lines(overall_average_Informed_pnl, type = "l", pch = 16, col = "red")
lines(overall_average_NoisyInformed1_pnl, type = "l", pch = 16, col = "green")
lines(overall_average_NoisyInformed2_pnl, type = "l", pch = 16, col = "yellow")
lines(overall_average_Noisy1_pnl, type = "l", pch = 16, col = "blue")
lines(overall_average_Noisy2_pnl, type = "l", pch = 16, col = "purple")
lines(overall_average_mr_pnl, type = "l", pch = 16, col = "orange")
# Add legend
legend("bottomleft", legend = c("Market Maker", "Informed", "Noisy Informed 1", "Noisy Informed 2", "Noisy 1", "Noisy 2", "Mean Reversion"), col = c("black", "red", "green", "yellow", "blue", "purple", "orange"), lty = 1, cex = 0.8)

# Initialize matrices to store averages for each position
average_MM_pos <- matrix(NA, nrow = 100, ncol = 10)
average_Informed_pos <- matrix(NA, nrow = 100, ncol = 10)
average_NoisyInformed1_pos <- matrix(NA, nrow = 100, ncol = 10)
average_NoisyInformed2_pos <- matrix(NA, nrow = 100, ncol = 10)
average_Noisy1_pos <- matrix(NA, nrow = 100, ncol = 10)
average_Noisy2_pos <- matrix(NA, nrow = 100, ncol = 10)
average_mr_pos <- matrix(NA, nrow = 100, ncol = 10)
# Loop through each simulation (n)
for (n in 1:10) {
MM_pos_set14 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_14[n, 7])), ", ")
Informed_pos_set14 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_14[n, 9])), ", ")
NoisyInformed1_pos_set14 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_14[n, 11])), ", ")
NoisyInformed2_pos_set14 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_14[n, 13])), ", ")
Noisy1_pos_set14 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_14[n, 15])), ", ")
Noisy2_pos_set14 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_14[n, 17])), ", ")
mr_pos_set14 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_14[n, 19])), ", ")
# Loop through each position (i)
for (i in 1:100) {
# Extract True and Expected values for the i-th position
MM_pos <- sapply(MM_pos_set14, function(x) as.numeric(x[i]))
Informed_pos <- sapply(Informed_pos_set14, function(x) as.numeric(x[i]))
NoisyInformed1_pos <- sapply(NoisyInformed1_pos_set14, function(x) as.numeric(x[i]))
NoisyInformed2_pos <- sapply(NoisyInformed2_pos_set14, function(x) as.numeric(x[i]))
Noisy1_pos <- sapply(Noisy1_pos_set14, function(x) as.numeric(x[i]))
Noisy2_pos <- sapply(Noisy2_pos_set14, function(x) as.numeric(x[i]))
mr_pos <- sapply(mr_pos_set14, function(x) as.numeric(x[i]))
# Calculate the average of True and Expected values for the i-th position
average_MM_pos[i, n] <- mean(MM_pos, na.rm = TRUE)
average_Informed_pos[i, n] <- mean(Informed_pos, na.rm = TRUE)
average_NoisyInformed1_pos[i, n] <- mean(NoisyInformed1_pos, na.rm = TRUE)
average_NoisyInformed2_pos[i, n] <- mean(NoisyInformed2_pos, na.rm = TRUE)
average_Noisy1_pos[i, n] <- mean(Noisy1_pos, na.rm = TRUE)
average_Noisy2_pos[i, n] <- mean(Noisy2_pos, na.rm = TRUE)
average_mr_pos[i, n] <- mean(mr_pos, na.rm = TRUE)
}
}
# Calculate the overall average for each position across all simulations
overall_average_MM_pos <- rowMeans(average_MM_pos, na.rm = TRUE)
overall_average_Informed_pos <- rowMeans(average_Informed_pos, na.rm = TRUE)
overall_average_NoisyInformed1_pos <- rowMeans(average_NoisyInformed1_pos, na.rm = TRUE)
overall_average_NoisyInformed2_pos <- rowMeans(average_NoisyInformed2_pos, na.rm = TRUE)
overall_average_Noisy1_pos <- rowMeans(average_Noisy1_pos, na.rm = TRUE)
overall_average_Noisy2_pos <- rowMeans(average_Noisy2_pos, na.rm = TRUE)
overall_average_mr_pos <- rowMeans(average_mr_pos, na.rm = TRUE)
# Plot the overall averages
plot(overall_average_MM_pos, type = "l", pch = 16, col = "black", main = "Overall Average Position", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_MM_pos, overall_average_Informed_pos, overall_average_NoisyInformed1_pos, overall_average_NoisyInformed2_pos, overall_average_Noisy1_pos, overall_average_Noisy2_pos, overall_average_mr_pos)), max(c(overall_average_MM_pos, overall_average_Informed_pos, overall_average_NoisyInformed1_pos, overall_average_NoisyInformed2_pos, overall_average_Noisy1_pos, overall_average_Noisy2_pos, overall_average_mr_pos))))
lines(overall_average_Informed_pos, type = "l", pch = 16, col = "red")
lines(overall_average_NoisyInformed1_pos, type = "l", pch = 16, col = "green")
lines(overall_average_NoisyInformed2_pos, type = "l", pch = 16, col = "yellow")
lines(overall_average_Noisy1_pos, type = "l", pch = 16, col = "blue")
lines(overall_average_Noisy2_pos, type = "l", pch = 16, col = "purple")
lines(overall_average_mr_pos, type = "l", pch = 16, col = "orange")
# Add legend
legend("bottomleft", legend = c("Market Maker", "Informed", "Noisy Informed 1", "Noisy Informed 2", "Noisy 1", "Noisy 2", "Mean Reversion"), col = c("black", "red", "green", "yellow", "blue", "purple", "orange"), lty = 1, cex = 0.8)

set15 (1 informed + 2 noisy informed + 2 noisy + 1 monmentum)
# Initialize matrices to store averages for each position
average_bid <- matrix(NA, nrow = 100, ncol = 10)
average_ask <- matrix(NA, nrow = 100, ncol = 10)
# Loop through each simulation (n)
for (n in 1:10) {
# Extract True values from the aggregated_results_4 dataframe
Bids_set15 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_15[n, 4])), ", ")
# Extract Expected values from the aggregated_results_4 dataframe
Asks_set15 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_15[n, 5])), ", ")
# Loop through each position (i)
for (i in 1:100) {
# Extract True and Expected values for the i-th position
Bids <- sapply(Bids_set15, function(x) as.numeric(x[i]))
Asks <- sapply(Asks_set15, function(x) as.numeric(x[i]))
# Calculate the average of True and Expected values for the i-th position
average_bid[i, n] <- mean(Bids, na.rm = TRUE)
average_ask[i, n] <- mean(Asks, na.rm = TRUE)
}
}
# Calculate the overall average for each position across all simulations
overall_average_bid <- rowMeans(average_bid, na.rm = TRUE)
overall_average_ask <- rowMeans(average_ask, na.rm = TRUE)
## True Value
# Initialize matrices to store averages for each position
average_true <- matrix(NA, nrow = 100, ncol = 10)
average_expected <- matrix(NA, nrow = 100, ncol = 10)
# Loop through each simulation (n)
for (n in 1:10) {
# Extract True values from the aggregated_results_4 dataframe
TrueValues_set15 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_15[n, 2])), ", ")
# Extract Expected values from the aggregated_results_4 dataframe
ExpectedValues_set15 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_15[n, 3])), ", ")
# Loop through each position (i)
for (i in 1:100) {
# Extract True and Expected values for the i-th position
True_values <- sapply(TrueValues_set15, function(x) as.numeric(x[i]))
Expected_values <- sapply(ExpectedValues_set15, function(x) as.numeric(x[i]))
# Calculate the average of True and Expected values for the i-th position
average_true[i, n] <- mean(True_values, na.rm = TRUE)
average_expected[i, n] <- mean(Expected_values, na.rm = TRUE)
}
}
# Calculate the overall average for each position across all simulations
overall_average_true <- rowMeans(average_true, na.rm = TRUE)
overall_average_expected <- rowMeans(average_expected, na.rm = TRUE)
# Plot the overall averages
#plot(overall_average_true, type = "l", pch = 16, col = "blue", main = "Overall Average of True vs Expected Values", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_true, overall_average_expected)), max(c(overall_average_true, overall_average_expected))))
#lines(overall_average_expected, type = "l", pch = 16, col = "red")
#legend("topright", legend = c("True Values", "Expected Values"), col = c("blue", "red"), lty = 1, cex = 0.8)
# Plot the overall averages
plot(overall_average_bid, type = "l", pch = 16, col = "blue", main = "Overall Average of Bids vs Asks & True vs Expected Values", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_bid, overall_average_ask, overall_average_true, overall_average_expected)), max(c(overall_average_bid, overall_average_ask, overall_average_true, overall_average_expected))))
lines(overall_average_ask, type = "l", pch = 16, col = "red")
lines(overall_average_true, type = "l", pch = 16, col = "green")
lines(overall_average_expected, type = "l", pch = 16, col = "purple")
legend("bottomleft", legend = c("Bids", "Asks", "True Value", "Expected Value"), col = c("blue", "red", "green", "purple"), lty = 1, cex = 0.8)

# Initialize matrices to store averages for each position
average_MM_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_Informed_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_NoisyInformed1_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_NoisyInformed2_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_Noisy1_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_Noisy2_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_mom_pnl <- matrix(NA, nrow = 100, ncol = 10)
# Loop through each simulation (n)
for (n in 1:10) {
MM_pnl_set15 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_15[n, 6])), ", ")
Informed_pnl_set15 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_15[n, 8])), ", ")
NoisyInformed1_pnl_set15 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_15[n, 10])), ", ")
NoisyInformed2_pnl_set15 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_15[n, 12])), ", ")
Noisy1_pnl_set15 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_15[n, 14])), ", ")
Noisy2_pnl_set15 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_15[n, 16])), ", ")
mom_pnl_set15 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_15[n, 18])), ", ")
# Loop through each position (i)
for (i in 1:100) {
# Extract True and Expected values for the i-th position
MM_pnl <- sapply(MM_pnl_set15, function(x) as.numeric(x[i]))
Informed_pnl <- sapply(Informed_pnl_set15, function(x) as.numeric(x[i]))
NoisyInformed1_pnl <- sapply(NoisyInformed1_pnl_set15, function(x) as.numeric(x[i]))
NoisyInformed2_pnl <- sapply(NoisyInformed2_pnl_set15, function(x) as.numeric(x[i]))
Noisy1_pnl <- sapply(Noisy1_pnl_set15, function(x) as.numeric(x[i]))
Noisy2_pnl <- sapply(Noisy2_pnl_set15, function(x) as.numeric(x[i]))
mom_pnl <- sapply(mom_pnl_set15, function(x) as.numeric(x[i]))
# Calculate the average of True and Expected values for the i-th position
average_MM_pnl[i, n] <- mean(MM_pnl, na.rm = TRUE)
average_Informed_pnl[i, n] <- mean(Informed_pnl, na.rm = TRUE)
average_NoisyInformed1_pnl[i, n] <- mean(NoisyInformed1_pnl, na.rm = TRUE)
average_NoisyInformed2_pnl[i, n] <- mean(NoisyInformed2_pnl, na.rm = TRUE)
average_Noisy1_pnl[i, n] <- mean(Noisy1_pnl, na.rm = TRUE)
average_Noisy2_pnl[i, n] <- mean(Noisy2_pnl, na.rm = TRUE)
average_mom_pnl[i, n] <- mean(mom_pnl, na.rm = TRUE)
}
}
# Calculate the overall average for each position across all simulations
overall_average_MM_pnl <- rowMeans(average_MM_pnl, na.rm = TRUE)
overall_average_Informed_pnl <- rowMeans(average_Informed_pnl, na.rm = TRUE)
overall_average_NoisyInformed1_pnl <- rowMeans(average_NoisyInformed1_pnl, na.rm = TRUE)
overall_average_NoisyInformed2_pnl <- rowMeans(average_NoisyInformed2_pnl, na.rm = TRUE)
overall_average_Noisy1_pnl <- rowMeans(average_Noisy1_pnl, na.rm = TRUE)
overall_average_Noisy2_pnl <- rowMeans(average_Noisy2_pnl, na.rm = TRUE)
overall_average_mom_pnl <- rowMeans(average_mom_pnl, na.rm = TRUE)
# Plot the overall averages
plot(overall_average_MM_pnl, type = "l", pch = 16, col = "black", main = "Overall Average PNL", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_MM_pnl, overall_average_Informed_pnl, overall_average_NoisyInformed1_pnl, overall_average_NoisyInformed2_pnl, overall_average_Noisy1_pnl, overall_average_Noisy2_pnl, overall_average_mom_pnl)), max(c(overall_average_MM_pnl, overall_average_Informed_pnl, overall_average_NoisyInformed1_pnl, overall_average_NoisyInformed2_pnl, overall_average_Noisy1_pnl, overall_average_Noisy2_pnl, overall_average_mom_pnl))))
lines(overall_average_Informed_pnl, type = "l", pch = 16, col = "red")
lines(overall_average_NoisyInformed1_pnl, type = "l", pch = 16, col = "green")
lines(overall_average_NoisyInformed2_pnl, type = "l", pch = 16, col = "yellow")
lines(overall_average_Noisy1_pnl, type = "l", pch = 16, col = "blue")
lines(overall_average_Noisy2_pnl, type = "l", pch = 16, col = "purple")
lines(overall_average_mom_pnl, type = "l", pch = 16, col = "orange")
# Add legend
legend("bottomleft", legend = c("Market Maker", "Informed", "Noisy Informed 1", "Noisy Informed 2", "Noisy 1", "Noisy 2", "Momentum"), col = c("black", "red", "green", "yellow", "blue", "purple", "orange"), lty = 1, cex = 0.8)

# Initialize matrices to store averages for each position
average_MM_pos <- matrix(NA, nrow = 100, ncol = 10)
average_Informed_pos <- matrix(NA, nrow = 100, ncol = 10)
average_NoisyInformed1_pos <- matrix(NA, nrow = 100, ncol = 10)
average_NoisyInformed2_pos <- matrix(NA, nrow = 100, ncol = 10)
average_Noisy1_pos <- matrix(NA, nrow = 100, ncol = 10)
average_Noisy2_pos <- matrix(NA, nrow = 100, ncol = 10)
average_mom_pos <- matrix(NA, nrow = 100, ncol = 10)
# Loop through each simulation (n)
for (n in 1:10) {
MM_pos_set15 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_15[n, 7])), ", ")
Informed_pos_set15 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_15[n, 9])), ", ")
NoisyInformed1_pos_set15 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_15[n, 11])), ", ")
NoisyInformed2_pos_set15 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_15[n, 13])), ", ")
Noisy1_pos_set15 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_15[n, 15])), ", ")
Noisy2_pos_set15 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_15[n, 17])), ", ")
mom_pos_set15 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_15[n, 19])), ", ")
# Loop through each position (i)
for (i in 1:100) {
# Extract True and Expected values for the i-th position
MM_pos <- sapply(MM_pos_set15, function(x) as.numeric(x[i]))
Informed_pos <- sapply(Informed_pos_set15, function(x) as.numeric(x[i]))
NoisyInformed1_pos <- sapply(NoisyInformed1_pos_set15, function(x) as.numeric(x[i]))
NoisyInformed2_pos <- sapply(NoisyInformed2_pos_set15, function(x) as.numeric(x[i]))
Noisy1_pos <- sapply(Noisy1_pos_set15, function(x) as.numeric(x[i]))
Noisy2_pos <- sapply(Noisy2_pos_set15, function(x) as.numeric(x[i]))
mom_pos <- sapply(mom_pos_set15, function(x) as.numeric(x[i]))
# Calculate the average of True and Expected values for the i-th position
average_MM_pos[i, n] <- mean(MM_pos, na.rm = TRUE)
average_Informed_pos[i, n] <- mean(Informed_pos, na.rm = TRUE)
average_NoisyInformed1_pos[i, n] <- mean(NoisyInformed1_pos, na.rm = TRUE)
average_NoisyInformed2_pos[i, n] <- mean(NoisyInformed2_pos, na.rm = TRUE)
average_Noisy1_pos[i, n] <- mean(Noisy1_pos, na.rm = TRUE)
average_Noisy2_pos[i, n] <- mean(Noisy2_pos, na.rm = TRUE)
average_mom_pos[i, n] <- mean(mom_pos, na.rm = TRUE)
}
}
# Calculate the overall average for each position across all simulations
overall_average_MM_pos <- rowMeans(average_MM_pos, na.rm = TRUE)
overall_average_Informed_pos <- rowMeans(average_Informed_pos, na.rm = TRUE)
overall_average_NoisyInformed1_pos <- rowMeans(average_NoisyInformed1_pos, na.rm = TRUE)
overall_average_NoisyInformed2_pos <- rowMeans(average_NoisyInformed2_pos, na.rm = TRUE)
overall_average_Noisy1_pos <- rowMeans(average_Noisy1_pos, na.rm = TRUE)
overall_average_Noisy2_pos <- rowMeans(average_Noisy2_pos, na.rm = TRUE)
overall_average_mom_pos <- rowMeans(average_mom_pos, na.rm = TRUE)
# Plot the overall averages
plot(overall_average_MM_pos, type = "l", pch = 16, col = "black", main = "Overall Average Position", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_MM_pos, overall_average_Informed_pos, overall_average_NoisyInformed1_pos, overall_average_NoisyInformed2_pos, overall_average_Noisy1_pos, overall_average_Noisy2_pos, overall_average_mom_pos)), max(c(overall_average_MM_pos, overall_average_Informed_pos, overall_average_NoisyInformed1_pos, overall_average_NoisyInformed2_pos, overall_average_Noisy1_pos, overall_average_Noisy2_pos, overall_average_mom_pos))))
lines(overall_average_Informed_pos, type = "l", pch = 16, col = "red")
lines(overall_average_NoisyInformed1_pos, type = "l", pch = 16, col = "green")
lines(overall_average_NoisyInformed2_pos, type = "l", pch = 16, col = "yellow")
lines(overall_average_Noisy1_pos, type = "l", pch = 16, col = "blue")
lines(overall_average_Noisy2_pos, type = "l", pch = 16, col = "purple")
lines(overall_average_mom_pos, type = "l", pch = 16, col = "orange")
# Add legend
legend("bottomleft", legend = c("Market Maker", "Informed", "Noisy Informed 1", "Noisy Informed 2", "Noisy 1", "Noisy 2", "Momentum"), col = c("black", "red", "green", "yellow", "blue", "purple", "orange"), lty = 1, cex = 0.8)

LS0tCnRpdGxlOiAiRGF0YSBBbmFseXNpcyBhbmQgR2FtZSBUaGVvcnkiCm91dHB1dDogaHRtbF9ub3RlYm9vawotLS0KCmBgYHtyfQpsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkoZHBseXIpCmxpYnJhcnkoc3RhdHMpCmBgYAoKIyMjIFRydWUgdmFsdWUgaW4gc2V0MSwgc2ltMQoKYGBge3J9ClRydWVWYWx1ZV9zZXQxIDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c18xWzEsIDJdKSksICIsICIpW1sxXV0KI2F2ZXJhZ2UgPC0gbWVhbihUcnVlVmFsdWVzX3NldDEpCnBsb3QoVHJ1ZVZhbHVlX3NldDEsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAiYmx1ZSIsIG1haW4gPSAiVHJ1ZSBWYWx1ZXMgaW4gc2ltMCIsIHhsYWIgPSAiSXRlcmF0aW9uIiwgeWxhYiA9ICJWYWx1ZSIpCgojVHJ1ZVZhbHVlX3NldDFfc2ltMCA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfMVsxLCAyXSkpLCAiLCAiKVtbMV1dCiN1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzFbMSwgMl0pCiNjbGVhbl9zdHIgPSBnc3ViKCJcXFt8XFxdIiwgIiIsIFRydWVWYWx1ZV9zaW0wKQojVHJ1ZVZhbHVlX3NldDFfc2ltMSA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfMVsyLCAyXSkpLCAiLCAiKVtbMV1dCgojcHJpbnQoVmFsdWVzKQojWCA8LSAxOjEwMAojcGxvdChUcnVlVmFsdWVfc2V0MV9zaW0wLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gImJsdWUiLCBtYWluID0gIlRydWUgVmFsdWVzIGluIHNpbTAiLCB4bGFiID0gIkl0ZXJhdGlvbiIsIHlsYWIgPSAiVmFsdWUiKQojcGxvdChUcnVlVmFsdWVfc2V0MV9zaW0xLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gImJsdWUiLCBtYWluID0gIlRydWUgVmFsdWVzIGluIHNpbTEiLCB4bGFiID0gIkl0ZXJhdGlvbiIsIHlsYWIgPSAiVmFsdWUiKQoKI2ZpdCA8LSBsbShWYWx1ZXMgfiBYKQojYWJsaW5lKGZpdCwgY29sID0gInJlZCIpCmBgYAojIyMgVHJ1ZSB2YWx1ZXMgaW4gc2V0IDEsIGFsbCBzaW0KCmBgYHtyfQojIEluaXRpYWxpemUgYW4gZW1wdHkgdmVjdG9yIHRvIHN0b3JlIHRoZSBUcnVlIHZhbHVlcwpUcnVlVmFsdWVzX3NldDEgPC0gbnVtZXJpYygpCgojIExvb3AgdGhyb3VnaCBlYWNoIGl0ZXJhdGlvbiAobikKZm9yIChuIGluIDE6MTApIHsKICAjIEV4dHJhY3QgVHJ1ZSB2YWx1ZXMgZnJvbSB0aGUgYWdncmVnYXRlZF9yZXN1bHRzXzEgZGF0YWZyYW1lCiAgVHJ1ZVZhbHVlX3NldDEgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzFbbiwgMl0pKSwgIiwgIilbWzFdXQogIAogICMgQXBwZW5kIHRoZSBUcnVlIHZhbHVlcyB0byB0aGUgdmVjdG9yCiAgVHJ1ZVZhbHVlc19zZXQxIDwtIGMoVHJ1ZVZhbHVlc19zZXQxLCBhcy5udW1lcmljKFRydWVWYWx1ZV9zZXQxKSkKfQoKIyBDYWxjdWxhdGUgdGhlIGF2ZXJhZ2Ugb2YgVHJ1ZSB2YWx1ZXMKYXZlcmFnZSA8LSBtZWFuKFRydWVWYWx1ZXNfc2V0MSkKCiMgUGxvdCB0aGUgYXZlcmFnZQpwbG90KFRydWVWYWx1ZXNfc2V0MSwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJibHVlIiwgbWFpbiA9ICJUcnVlIFZhbHVlcyBpbiBzZXQgMSIsIHhsYWIgPSAiSXRlcmF0aW9uIiwgeWxhYiA9ICJWYWx1ZSIpCgojIEFkZCBhIGhvcml6b250YWwgbGluZSBmb3IgdGhlIGF2ZXJhZ2UKYWJsaW5lKGggPSBhdmVyYWdlLCBjb2wgPSAicmVkIiwgbHdkID0gMikKCmBgYAoKIyMjIEV4cGVjdGVkIHZhbHVlIGluIHNldDEsIGFsbCBzaW0KCmBgYHtyfQojIEluaXRpYWxpemUgYW4gZW1wdHkgdmVjdG9yIHRvIHN0b3JlIHRoZSBUcnVlIHZhbHVlcwpFeHBlY3RlZFZhbHVlc19zZXQxIDwtIG51bWVyaWMoKQoKIyBMb29wIHRocm91Z2ggZWFjaCBpdGVyYXRpb24gKG4pCmZvciAobiBpbiAxOjEwKSB7CiAgIyBFeHRyYWN0IFRydWUgdmFsdWVzIGZyb20gdGhlIGFnZ3JlZ2F0ZWRfcmVzdWx0c18xIGRhdGFmcmFtZQogIEV4cGVjdGVkVmFsdWVfc2V0MSA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfMVtuLCAzXSkpLCAiLCAiKVtbMV1dCiAgCiAgIyBBcHBlbmQgdGhlIFRydWUgdmFsdWVzIHRvIHRoZSB2ZWN0b3IKICBFeHBlY3RlZFZhbHVlc19zZXQxIDwtIGMoRXhwZWN0ZWRWYWx1ZXNfc2V0MSwgYXMubnVtZXJpYyhFeHBlY3RlZFZhbHVlX3NldDEpKQp9CgojIENhbGN1bGF0ZSB0aGUgYXZlcmFnZSBvZiBUcnVlIHZhbHVlcwphdmVyYWdlIDwtIG1lYW4oRXhwZWN0ZWRWYWx1ZXNfc2V0MSkKCiMgUGxvdCB0aGUgYXZlcmFnZQpwbG90KEV4cGVjdGVkVmFsdWVzX3NldDEsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAiYmx1ZSIsIG1haW4gPSAiRXhwZWN0ZWQgVmFsdWVzIGluIHNldCAxIiwgeGxhYiA9ICJJdGVyYXRpb24iLCB5bGFiID0gIlZhbHVlIikKCiMgQWRkIGEgaG9yaXpvbnRhbCBsaW5lIGZvciB0aGUgYXZlcmFnZQphYmxpbmUoaCA9IGF2ZXJhZ2UsIGNvbCA9ICJyZWQiLCBsd2QgPSAyKQoKYGBgCgojIyMgVHJ1ZSBhbmQgRXhwZWN0ZWQgVmFsdWVzIGluIHNldCAxCgpgYGB7cn0KIyBJbml0aWFsaXplIGVtcHR5IHZlY3RvcnMgdG8gc3RvcmUgdHJ1ZSBhbmQgZXhwZWN0ZWQgdmFsdWVzClRydWVWYWx1ZXNfc2V0MSA8LSBudW1lcmljKCkKRXhwZWN0ZWRWYWx1ZXNfc2V0MSA8LSBudW1lcmljKCkKCiMgTG9vcCB0aHJvdWdoIGVhY2ggaXRlcmF0aW9uIChuKQpmb3IgKG4gaW4gMToxMCkgewogICMgRXh0cmFjdCBUcnVlIHZhbHVlcyBmcm9tIHRoZSBhZ2dyZWdhdGVkX3Jlc3VsdHNfMSBkYXRhZnJhbWUKICBUcnVlVmFsdWVfc2V0MSA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfMVtuLCAyXSkpLCAiLCAiKVtbMV1dCiAgCiAgIyBFeHRyYWN0IEV4cGVjdGVkIHZhbHVlcyBmcm9tIHRoZSBhZ2dyZWdhdGVkX3Jlc3VsdHNfMSBkYXRhZnJhbWUKICBFeHBlY3RlZFZhbHVlX3NldDEgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzFbbiwgM10pKSwgIiwgIilbWzFdXQogIAogICMgQXBwZW5kIHRoZSBUcnVlIGFuZCBFeHBlY3RlZCB2YWx1ZXMgdG8gdGhlaXIgcmVzcGVjdGl2ZSB2ZWN0b3JzCiAgVHJ1ZVZhbHVlc19zZXQxIDwtIGMoVHJ1ZVZhbHVlc19zZXQxLCBhcy5udW1lcmljKFRydWVWYWx1ZV9zZXQxKSkKICBFeHBlY3RlZFZhbHVlc19zZXQxIDwtIGMoRXhwZWN0ZWRWYWx1ZXNfc2V0MSwgYXMubnVtZXJpYyhFeHBlY3RlZFZhbHVlX3NldDEpKQp9CgojIENhbGN1bGF0ZSB0aGUgYXZlcmFnZSBvZiBUcnVlIHZhbHVlcwphdmVyYWdlX3RydWUgPC0gbWVhbihUcnVlVmFsdWVzX3NldDEpCgojIENhbGN1bGF0ZSB0aGUgYXZlcmFnZSBvZiBFeHBlY3RlZCB2YWx1ZXMKYXZlcmFnZV9leHBlY3RlZCA8LSBtZWFuKEV4cGVjdGVkVmFsdWVzX3NldDEpCgojIFBsb3QgVHJ1ZSBhbmQgRXhwZWN0ZWQgdmFsdWVzIG9uIHRoZSBzYW1lIHBsb3QKcGxvdChUcnVlVmFsdWVzX3NldDEsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAiYmx1ZSIsIG1haW4gPSAiVHJ1ZSB2cyBFeHBlY3RlZCBWYWx1ZXMgaW4gc2V0IDEiLCB4bGFiID0gIkl0ZXJhdGlvbiIsIHlsYWIgPSAiVmFsdWUiKQpsaW5lcyhFeHBlY3RlZFZhbHVlc19zZXQxLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gInJlZCIpCgojIEFkZCBsZWdlbmQKbGVnZW5kKCJ0b3ByaWdodCIsIGxlZ2VuZCA9IGMoIlRydWUgVmFsdWVzIiwgIkV4cGVjdGVkIFZhbHVlcyIpLCBjb2wgPSBjKCJibHVlIiwgInJlZCIpLCBsdHkgPSAxLCBjZXggPSAwLjgpCgojIEFkZCBob3Jpem9udGFsIGxpbmVzIGZvciB0aGUgYXZlcmFnZXMKYWJsaW5lKGggPSBhdmVyYWdlX3RydWUsIGNvbCA9ICJibHVlIiwgbHdkID0gMSkKYWJsaW5lKGggPSBhdmVyYWdlX2V4cGVjdGVkLCBjb2wgPSAicmVkIiwgbHdkID0gMSkKYGBgCgojIyMgQmlkcyBpbiBzZXQxLCBzaW0xCgoKYGBge3J9CkJpZHNfc2V0MSA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfMVsxLCA0XSkpLCAiLCAiKVtbMV1dCiNhdmVyYWdlIDwtIG1lYW4oVHJ1ZVZhbHVlc19zZXQxKQpwbG90KEJpZHNfc2V0MSwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJibHVlIiwgbWFpbiA9ICJUcnVlIFZhbHVlcyBpbiBzaW0wIiwgeGxhYiA9ICJJdGVyYXRpb24iLCB5bGFiID0gIlZhbHVlIikKYGBgCgojIyMgQmlkcyBpbiBzZXQgMSwgYWxsIHNpbQoKYGBge3J9CiMgSW5pdGlhbGl6ZSBhbiBlbXB0eSB2ZWN0b3IgdG8gc3RvcmUgdGhlIFRydWUgdmFsdWVzCkJpZHNfc2V0MSA8LSBudW1lcmljKCkKCiMgTG9vcCB0aHJvdWdoIGVhY2ggaXRlcmF0aW9uIChuKQpmb3IgKG4gaW4gMToxMCkgewogICMgRXh0cmFjdCBUcnVlIHZhbHVlcyBmcm9tIHRoZSBhZ2dyZWdhdGVkX3Jlc3VsdHNfMSBkYXRhZnJhbWUKICBCaWRfc2V0MSA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfMVtuLCA0XSkpLCAiLCAiKVtbMV1dCiAgCiAgIyBBcHBlbmQgdGhlIFRydWUgdmFsdWVzIHRvIHRoZSB2ZWN0b3IgKGNvcnJlY3RlZCB0eXBvKQogIEJpZHNfc2V0MSA8LSBjKEJpZHNfc2V0MSwgYXMubnVtZXJpYyhCaWRfc2V0MSkpCn0KCiMgQ2hlY2sgaWYgdGhlIHZlY3RvciBpcyBwcm9wZXJseSBwb3B1bGF0ZWQKI3ByaW50KEJpZHNfc2V0MSkKCiMgQ2FsY3VsYXRlIHRoZSBhdmVyYWdlIG9mIFRydWUgdmFsdWVzCmF2ZXJhZ2UgPC0gbWVhbihCaWRzX3NldDEsIG5hLnJtID0gVFJVRSkKCiMgUGxvdCB0aGUgdmFsdWVzCnBsb3QoQmlkc19zZXQxLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gImJsdWUiLCBtYWluID0gIkJpZCB2cyBBc2sgaW4gc2V0IDEiLCB4bGFiID0gIkl0ZXJhdGlvbiIsIHlsYWIgPSAiVmFsdWUiKQoKIyBBZGQgYSBob3Jpem9udGFsIGxpbmUgZm9yIHRoZSBhdmVyYWdlCmFibGluZShoID0gYXZlcmFnZSwgY29sID0gInJlZCIsIGx3ZCA9IDIpCgpgYGAKCiMjIyBCaWRzIGFuZCBBc2tzIE92ZXJhbGwKCmBgYHtyfQojIEluaXRpYWxpemUgZW1wdHkgdmVjdG9ycyB0byBzdG9yZSB0aGUgQmlkIGFuZCBBc2sgdmFsdWVzCkJpZHNfc2V0MSA8LSBudW1lcmljKCkKQXNrc19zZXQxIDwtIG51bWVyaWMoKQoKIyBMb29wIHRocm91Z2ggZWFjaCBpdGVyYXRpb24gKG4pCmZvciAobiBpbiAxOjEwKSB7CiAgIyBFeHRyYWN0IEJpZCB2YWx1ZXMgZnJvbSB0aGUgYWdncmVnYXRlZF9yZXN1bHRzXzEgZGF0YWZyYW1lCiAgQmlkX3NldDEgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzFbbiwgNF0pKSwgIiwgIilbWzFdXQogIAogICMgRXh0cmFjdCBBc2sgdmFsdWVzIGZyb20gdGhlIGFnZ3JlZ2F0ZWRfcmVzdWx0c18xIGRhdGFmcmFtZSAobmV4dCBjb2x1bW4pCiAgQXNrX3NldDEgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzFbbiwgNV0pKSwgIiwgIilbWzFdXQogIAogICMgQXBwZW5kIHRoZSBCaWQgYW5kIEFzayB2YWx1ZXMgdG8gdGhlaXIgcmVzcGVjdGl2ZSB2ZWN0b3JzCiAgQmlkc19zZXQxIDwtIGMoQmlkc19zZXQxLCBhcy5udW1lcmljKEJpZF9zZXQxKSkKICBBc2tzX3NldDEgPC0gYyhBc2tzX3NldDEsIGFzLm51bWVyaWMoQXNrX3NldDEpKQp9CgojIENhbGN1bGF0ZSB0aGUgYXZlcmFnZSBvZiBCaWQgYW5kIEFzayB2YWx1ZXMKYXZlcmFnZV9iaWRzIDwtIG1lYW4oQmlkc19zZXQxLCBuYS5ybSA9IFRSVUUpCmF2ZXJhZ2VfYXNrcyA8LSBtZWFuKEFza3Nfc2V0MSwgbmEucm0gPSBUUlVFKQoKIyBQbG90IHRoZSBCaWQgYW5kIEFzayB2YWx1ZXMgb24gdGhlIHNhbWUgcGxvdApwbG90KEJpZHNfc2V0MSwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJibHVlIiwgbWFpbiA9ICJCaWRzIHZzIEFza3MgaW4gc2V0IDEiLCB4bGFiID0gIkl0ZXJhdGlvbiIsIHlsYWIgPSAiVmFsdWUiKQpsaW5lcyhBc2tzX3NldDEsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAicmVkIikKCiMgQWRkIGxlZ2VuZApsZWdlbmQoInRvcHJpZ2h0IiwgbGVnZW5kID0gYygiQmlkcyIsICJBc2tzIiksIGNvbCA9IGMoImJsdWUiLCAicmVkIiksIGx0eSA9IDEsIGNleCA9IDAuOCkKCiMgQWRkIGhvcml6b250YWwgbGluZXMgZm9yIHRoZSBhdmVyYWdlcwphYmxpbmUoaCA9IGF2ZXJhZ2VfYmlkcywgY29sID0gImJsdWUiLCBsdHkgPSAxKQphYmxpbmUoaCA9IGF2ZXJhZ2VfYXNrcywgY29sID0gInJlZCIsIGx0eSA9IDEpCgpgYGAKCiMjIyBTdGFydCBGcm9tIEhlcmUKCgojIyBzZXQgMSAoNiBpbmZvcm1lZCkKCmBgYHtyfQojIEluaXRpYWxpemUgbWF0cmljZXMgdG8gc3RvcmUgYXZlcmFnZXMgZm9yIGVhY2ggcG9zaXRpb24KYXZlcmFnZV90cnVlIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX2V4cGVjdGVkIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQoKIyBMb29wIHRocm91Z2ggZWFjaCBzaW11bGF0aW9uIChuKQpmb3IgKG4gaW4gMToxMCkgewogICMgRXh0cmFjdCBUcnVlIHZhbHVlcyBmcm9tIHRoZSBhZ2dyZWdhdGVkX3Jlc3VsdHNfNCBkYXRhZnJhbWUKICBUcnVlVmFsdWVzX3NldDEgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzFbbiwgMl0pKSwgIiwgIikKICAKICAjIEV4dHJhY3QgRXhwZWN0ZWQgdmFsdWVzIGZyb20gdGhlIGFnZ3JlZ2F0ZWRfcmVzdWx0c180IGRhdGFmcmFtZQogIEV4cGVjdGVkVmFsdWVzX3NldDEgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzFbbiwgM10pKSwgIiwgIikKICAKICAjIExvb3AgdGhyb3VnaCBlYWNoIHBvc2l0aW9uIChpKQogIGZvciAoaSBpbiAxOjEwMCkgewogICAgIyBFeHRyYWN0IFRydWUgYW5kIEV4cGVjdGVkIHZhbHVlcyBmb3IgdGhlIGktdGggcG9zaXRpb24KICAgIFRydWVfdmFsdWVzIDwtIHNhcHBseShUcnVlVmFsdWVzX3NldDEsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICBFeHBlY3RlZF92YWx1ZXMgPC0gc2FwcGx5KEV4cGVjdGVkVmFsdWVzX3NldDEsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICAKICAgICMgQ2FsY3VsYXRlIHRoZSBhdmVyYWdlIG9mIFRydWUgYW5kIEV4cGVjdGVkIHZhbHVlcyBmb3IgdGhlIGktdGggcG9zaXRpb24KICAgIGF2ZXJhZ2VfdHJ1ZVtpLCBuXSA8LSBtZWFuKFRydWVfdmFsdWVzLCBuYS5ybSA9IFRSVUUpCiAgICBhdmVyYWdlX2V4cGVjdGVkW2ksIG5dIDwtIG1lYW4oRXhwZWN0ZWRfdmFsdWVzLCBuYS5ybSA9IFRSVUUpCiAgfQp9CgojIENhbGN1bGF0ZSB0aGUgb3ZlcmFsbCBhdmVyYWdlIGZvciBlYWNoIHBvc2l0aW9uIGFjcm9zcyBhbGwgc2ltdWxhdGlvbnMKb3ZlcmFsbF9hdmVyYWdlX3RydWUgPC0gcm93TWVhbnMoYXZlcmFnZV90cnVlLCBuYS5ybSA9IFRSVUUpCm92ZXJhbGxfYXZlcmFnZV9leHBlY3RlZCA8LSByb3dNZWFucyhhdmVyYWdlX2V4cGVjdGVkLCBuYS5ybSA9IFRSVUUpCgojIFBsb3QgdGhlIG92ZXJhbGwgYXZlcmFnZXMKcGxvdChvdmVyYWxsX2F2ZXJhZ2VfdHJ1ZSwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJibHVlIiwgbWFpbiA9ICJPdmVyYWxsIEF2ZXJhZ2Ugb2YgVHJ1ZSB2cyBFeHBlY3RlZCBWYWx1ZXMiLCB4bGFiID0gIlBvc2l0aW9uIGluIExpc3QiLCB5bGFiID0gIlZhbHVlIiwgeWxpbSA9IGMobWluKGMob3ZlcmFsbF9hdmVyYWdlX3RydWUsIG92ZXJhbGxfYXZlcmFnZV9leHBlY3RlZCkpLCBtYXgoYyhvdmVyYWxsX2F2ZXJhZ2VfdHJ1ZSwgb3ZlcmFsbF9hdmVyYWdlX2V4cGVjdGVkKSkpKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfZXhwZWN0ZWQsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAicmVkIikKbGVnZW5kKCJ0b3ByaWdodCIsIGxlZ2VuZCA9IGMoIlRydWUgVmFsdWVzIiwgIkV4cGVjdGVkIFZhbHVlcyIpLCBjb2wgPSBjKCJibHVlIiwgInJlZCIpLCBsdHkgPSAxLCBjZXggPSAwLjgpCmBgYAoKCgpgYGB7cn0KIyBJbml0aWFsaXplIG1hdHJpY2VzIHRvIHN0b3JlIGF2ZXJhZ2VzIGZvciBlYWNoIHBvc2l0aW9uCmF2ZXJhZ2VfYmlkIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX2FzayA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKCiMgTG9vcCB0aHJvdWdoIGVhY2ggc2ltdWxhdGlvbiAobikKZm9yIChuIGluIDE6MTApIHsKICAjIEV4dHJhY3QgVHJ1ZSB2YWx1ZXMgZnJvbSB0aGUgYWdncmVnYXRlZF9yZXN1bHRzXzQgZGF0YWZyYW1lCiAgQmlkc19zZXQxIDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c18xW24sIDRdKSksICIsICIpCiAgCiAgIyBFeHRyYWN0IEV4cGVjdGVkIHZhbHVlcyBmcm9tIHRoZSBhZ2dyZWdhdGVkX3Jlc3VsdHNfNCBkYXRhZnJhbWUKICBBc2tzX3NldDEgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzFbbiwgNV0pKSwgIiwgIikKICAKICAjIExvb3AgdGhyb3VnaCBlYWNoIHBvc2l0aW9uIChpKQogIGZvciAoaSBpbiAxOjEwMCkgewogICAgIyBFeHRyYWN0IFRydWUgYW5kIEV4cGVjdGVkIHZhbHVlcyBmb3IgdGhlIGktdGggcG9zaXRpb24KICAgIEJpZHMgPC0gc2FwcGx5KEJpZHNfc2V0MSwgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIEFza3MgPC0gc2FwcGx5KEFza3Nfc2V0MSwgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIAogICAgIyBDYWxjdWxhdGUgdGhlIGF2ZXJhZ2Ugb2YgVHJ1ZSBhbmQgRXhwZWN0ZWQgdmFsdWVzIGZvciB0aGUgaS10aCBwb3NpdGlvbgogICAgYXZlcmFnZV9iaWRbaSwgbl0gPC0gbWVhbihCaWRzLCBuYS5ybSA9IFRSVUUpCiAgICBhdmVyYWdlX2Fza1tpLCBuXSA8LSBtZWFuKEFza3MsIG5hLnJtID0gVFJVRSkKICB9Cn0KCiMgQ2FsY3VsYXRlIHRoZSBvdmVyYWxsIGF2ZXJhZ2UgZm9yIGVhY2ggcG9zaXRpb24gYWNyb3NzIGFsbCBzaW11bGF0aW9ucwpvdmVyYWxsX2F2ZXJhZ2VfYmlkIDwtIHJvd01lYW5zKGF2ZXJhZ2VfYmlkLCBuYS5ybSA9IFRSVUUpCm92ZXJhbGxfYXZlcmFnZV9hc2sgPC0gcm93TWVhbnMoYXZlcmFnZV9hc2ssIG5hLnJtID0gVFJVRSkKCiMjIFRydWUgVmFsdWUKIyBJbml0aWFsaXplIG1hdHJpY2VzIHRvIHN0b3JlIGF2ZXJhZ2VzIGZvciBlYWNoIHBvc2l0aW9uCmF2ZXJhZ2VfdHJ1ZSA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKYXZlcmFnZV9leHBlY3RlZCA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKCiMgTG9vcCB0aHJvdWdoIGVhY2ggc2ltdWxhdGlvbiAobikKZm9yIChuIGluIDE6MTApIHsKICAjIEV4dHJhY3QgVHJ1ZSB2YWx1ZXMgZnJvbSB0aGUgYWdncmVnYXRlZF9yZXN1bHRzXzQgZGF0YWZyYW1lCiAgVHJ1ZVZhbHVlc19zZXQxIDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c18xW24sIDJdKSksICIsICIpCiAgCiAgIyBFeHRyYWN0IEV4cGVjdGVkIHZhbHVlcyBmcm9tIHRoZSBhZ2dyZWdhdGVkX3Jlc3VsdHNfNCBkYXRhZnJhbWUKICBFeHBlY3RlZFZhbHVlc19zZXQxIDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c18xW24sIDNdKSksICIsICIpCiAgCiAgIyBMb29wIHRocm91Z2ggZWFjaCBwb3NpdGlvbiAoaSkKICBmb3IgKGkgaW4gMToxMDApIHsKICAgICMgRXh0cmFjdCBUcnVlIGFuZCBFeHBlY3RlZCB2YWx1ZXMgZm9yIHRoZSBpLXRoIHBvc2l0aW9uCiAgICBUcnVlX3ZhbHVlcyA8LSBzYXBwbHkoVHJ1ZVZhbHVlc19zZXQxLCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgRXhwZWN0ZWRfdmFsdWVzIDwtIHNhcHBseShFeHBlY3RlZFZhbHVlc19zZXQxLCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgCiAgICAjIENhbGN1bGF0ZSB0aGUgYXZlcmFnZSBvZiBUcnVlIGFuZCBFeHBlY3RlZCB2YWx1ZXMgZm9yIHRoZSBpLXRoIHBvc2l0aW9uCiAgICBhdmVyYWdlX3RydWVbaSwgbl0gPC0gbWVhbihUcnVlX3ZhbHVlcywgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9leHBlY3RlZFtpLCBuXSA8LSBtZWFuKEV4cGVjdGVkX3ZhbHVlcywgbmEucm0gPSBUUlVFKQogIH0KfQoKIyBDYWxjdWxhdGUgdGhlIG92ZXJhbGwgYXZlcmFnZSBmb3IgZWFjaCBwb3NpdGlvbiBhY3Jvc3MgYWxsIHNpbXVsYXRpb25zCm92ZXJhbGxfYXZlcmFnZV90cnVlIDwtIHJvd01lYW5zKGF2ZXJhZ2VfdHJ1ZSwgbmEucm0gPSBUUlVFKQpvdmVyYWxsX2F2ZXJhZ2VfZXhwZWN0ZWQgPC0gcm93TWVhbnMoYXZlcmFnZV9leHBlY3RlZCwgbmEucm0gPSBUUlVFKQoKIyBQbG90IHRoZSBvdmVyYWxsIGF2ZXJhZ2VzCiNwbG90KG92ZXJhbGxfYXZlcmFnZV90cnVlLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gImJsdWUiLCBtYWluID0gIk92ZXJhbGwgQXZlcmFnZSBvZiBUcnVlIHZzIEV4cGVjdGVkIFZhbHVlcyIsIHhsYWIgPSAiUG9zaXRpb24gaW4gTGlzdCIsIHlsYWIgPSAiVmFsdWUiLCB5bGltID0gYyhtaW4oYyhvdmVyYWxsX2F2ZXJhZ2VfdHJ1ZSwgb3ZlcmFsbF9hdmVyYWdlX2V4cGVjdGVkKSksIG1heChjKG92ZXJhbGxfYXZlcmFnZV90cnVlLCBvdmVyYWxsX2F2ZXJhZ2VfZXhwZWN0ZWQpKSkpCiNsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfZXhwZWN0ZWQsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAicmVkIikKI2xlZ2VuZCgidG9wcmlnaHQiLCBsZWdlbmQgPSBjKCJUcnVlIFZhbHVlcyIsICJFeHBlY3RlZCBWYWx1ZXMiKSwgY29sID0gYygiYmx1ZSIsICJyZWQiKSwgbHR5ID0gMSwgY2V4ID0gMC44KQoKIyBQbG90IHRoZSBvdmVyYWxsIGF2ZXJhZ2VzCnBsb3Qob3ZlcmFsbF9hdmVyYWdlX2JpZCwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJibHVlIiwgbWFpbiA9ICJPdmVyYWxsIEF2ZXJhZ2Ugb2YgQmlkcyB2cyBBc2tzICYgVHJ1ZSB2cyBFeHBlY3RlZCBWYWx1ZXMiLCB4bGFiID0gIlBvc2l0aW9uIGluIExpc3QiLCB5bGFiID0gIlZhbHVlIiwgeWxpbSA9IGMobWluKGMob3ZlcmFsbF9hdmVyYWdlX2JpZCwgb3ZlcmFsbF9hdmVyYWdlX2FzaykpLCBtYXgoYyhvdmVyYWxsX2F2ZXJhZ2VfYmlkLCBvdmVyYWxsX2F2ZXJhZ2VfYXNrKSkpKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfYXNrLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gInJlZCIpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV90cnVlLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gImdyZWVuIikKbGluZXMob3ZlcmFsbF9hdmVyYWdlX2V4cGVjdGVkLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gInB1cnBsZSIpCmxlZ2VuZCgidG9wcmlnaHQiLCBsZWdlbmQgPSBjKCJCaWRzIiwgIkFza3MiLCAiVHJ1ZSBWYWx1ZSIsICJFeHBlY3RlZCBWYWx1ZSIpLCBjb2wgPSBjKCJibHVlIiwgInJlZCIsICJncmVlbiIsICJwdXJwbGUiKSwgbHR5ID0gMSwgY2V4ID0gMC44KQpgYGAKCiMjIyBQaWNrIHNpbSA1IGFzIGEgZXhhbXBsZQoKYGBge3J9ClRydWVWYWx1ZV9zZXQxIDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c18xWzUsIDJdKSksICIsICIpW1sxXV0KCkJpZHNfc2V0MSA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfMVs1LCA0XSkpLCAiLCAiKVtbMV1dCkFza3Nfc2V0MSA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfMVs1LCA1XSkpLCAiLCAiKVtbMV1dCgpwbG90KFRydWVWYWx1ZV9zZXQxLCAKICAgICB0eXBlID0gImwiLCAKICAgICBwY2ggPSAxNiwgCiAgICAgY29sID0gImdyZWVuIiwgCiAgICAgbWFpbiA9ICJUcnVlIFZhbHVlcyBpbiBzaW0gNSIsIAogICAgIHhsYWIgPSAiSXRlcmF0aW9uIiwgCiAgICAgeWxhYiA9ICJWYWx1ZSIsIAogICAgIHlsaW0gPSBjKG1pbihjKGFzLm51bWVyaWMoVHJ1ZVZhbHVlX3NldDEpLCBhcy5udW1lcmljKEJpZHNfc2V0MSksIGFzLm51bWVyaWMoQXNrc19zZXQxKSkpLCAKICAgICAgICAgICAgICBtYXgoYyhhcy5udW1lcmljKFRydWVWYWx1ZV9zZXQxKSwgYXMubnVtZXJpYyhCaWRzX3NldDEpLCBhcy5udW1lcmljKEFza3Nfc2V0MSkpKSkpCmxpbmVzKEJpZHNfc2V0MSwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJibHVlIikKbGluZXMoQXNrc19zZXQxLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gInJlZCIpCmxlZ2VuZCgidG9wbGVmdCIsIGxlZ2VuZCA9IGMoIkJpZHMiLCAiQXNrcyIsICJUcnVlIFZhbHVlIiksIGNvbCA9IGMoImJsdWUiLCAicmVkIiwgImdyZWVuIiksIGx0eSA9IDEsIGNleCA9IDAuOCkKCmBgYAoKYGBge3J9Ck1NX3BubF9zZXQxIDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c18xWzUsIDZdKSksICIsICIpW1sxXV0KSW5mb3JtZWQxX3BubF9zZXQxIDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c18xWzUsIDhdKSksICIsICIpW1sxXV0KSW5mb3JtZWQyX3BubF9zZXQxIDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c18xWzUsIDEwXSkpLCAiLCAiKVtbMV1dCkluZm9ybWVkM19wbmxfc2V0MSA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfMVs1LCAxMl0pKSwgIiwgIilbWzFdXQpJbmZvcm1lZDRfcG5sX3NldDEgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzFbNSwgMTRdKSksICIsICIpW1sxXV0KSW5mb3JtZWQ1X3BubF9zZXQxIDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c18xWzUsIDE2XSkpLCAiLCAiKVtbMV1dCkluZm9ybWVkNl9wbmxfc2V0MSA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfMVs1LCAxOF0pKSwgIiwgIilbWzFdXQoKI0JpZHNfc2V0MSA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfMVs1LCA0XSkpLCAiLCAiKVtbMV1dCiNBc2tzX3NldDEgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzFbNSwgNV0pKSwgIiwgIilbWzFdXQoKcGxvdChNTV9wbmxfc2V0MSwgCiAgICAgdHlwZSA9ICJsIiwgCiAgICAgcGNoID0gMTYsIAogICAgIGNvbCA9ICJibGFjayIsIAogICAgIG1haW4gPSAiUE5MIHNpbSA1IiwgCiAgICAgeGxhYiA9ICJQb3NpdGlvbiBpbiBMaXN0IiwgCiAgICAgeWxhYiA9ICJWYWx1ZSIsCiAgICAgeWxpbSA9IGMobWluKGMoYXMubnVtZXJpYyhNTV9wbmxfc2V0MSksIGFzLm51bWVyaWMoSW5mb3JtZWQxX3BubF9zZXQxKSwgYXMubnVtZXJpYyhJbmZvcm1lZDJfcG5sX3NldDEpLCBhcy5udW1lcmljKEluZm9ybWVkM19wbmxfc2V0MSksIGFzLm51bWVyaWMoSW5mb3JtZWQ0X3BubF9zZXQxKSwgYXMubnVtZXJpYyhJbmZvcm1lZDVfcG5sX3NldDEpLCBhcy5udW1lcmljKEluZm9ybWVkNl9wbmxfc2V0MSkpKSwgCiAgICAgICAgICAgICAgbWF4KGMoYXMubnVtZXJpYyhNTV9wbmxfc2V0MSksIGFzLm51bWVyaWMoSW5mb3JtZWQxX3BubF9zZXQxKSwgYXMubnVtZXJpYyhJbmZvcm1lZDJfcG5sX3NldDEpLCBhcy5udW1lcmljKEluZm9ybWVkM19wbmxfc2V0MSksIGFzLm51bWVyaWMoSW5mb3JtZWQ0X3BubF9zZXQxKSwgYXMubnVtZXJpYyhJbmZvcm1lZDVfcG5sX3NldDEpLCBhcy5udW1lcmljKEluZm9ybWVkNl9wbmxfc2V0MSkpKSkpCgpsaW5lcyhJbmZvcm1lZDFfcG5sX3NldDEsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAicmVkIikKbGluZXMoSW5mb3JtZWQyX3BubF9zZXQxLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gImdyZWVuIikKbGluZXMoSW5mb3JtZWQzX3BubF9zZXQxLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gInllbGxvdyIpCmxpbmVzKEluZm9ybWVkNF9wbmxfc2V0MSwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJibHVlIikKbGluZXMoSW5mb3JtZWQ1X3BubF9zZXQxLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gInB1cnBsZSIpCmxpbmVzKEluZm9ybWVkNl9wbmxfc2V0MSwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJvcmFuZ2UiKQoKIyBBZGQgbGVnZW5kCmxlZ2VuZCgiYm90dG9tbGVmdCIsIGxlZ2VuZCA9IGMoIk1hcmtldCBNYWtlciIsICJJbmZvcm1lZCAxIiwgIkluZm9ybWVkIDIiLCAiSW5mb3JtZWQgMyIsICJJbmZvcm1lZCA0IiwgIkluZm9ybWVkIDUiLCAiSW5mb3JtZWQgNiIpLCBjb2wgPSBjKCJibGFjayIsICJyZWQiLCAiZ3JlZW4iLCAieWVsbG93IiwgImJsdWUiLCAicHVycGxlIiwgIm9yYW5nZSIpLCBsdHkgPSAxLCBjZXggPSAwLjgpCmBgYAoKYGBge3J9Ck1NX3BubF9zZXQxIDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c18xWzUsIDddKSksICIsICIpW1sxXV0KSW5mb3JtZWQxX3BubF9zZXQxIDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c18xWzUsIDldKSksICIsICIpW1sxXV0KSW5mb3JtZWQyX3BubF9zZXQxIDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c18xWzUsIDExXSkpLCAiLCAiKVtbMV1dCkluZm9ybWVkM19wbmxfc2V0MSA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfMVs1LCAxM10pKSwgIiwgIilbWzFdXQpJbmZvcm1lZDRfcG5sX3NldDEgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzFbNSwgMTVdKSksICIsICIpW1sxXV0KSW5mb3JtZWQ1X3BubF9zZXQxIDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c18xWzUsIDE3XSkpLCAiLCAiKVtbMV1dCkluZm9ybWVkNl9wbmxfc2V0MSA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfMVs1LCAxOV0pKSwgIiwgIilbWzFdXQoKI0JpZHNfc2V0MSA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfMVs1LCA0XSkpLCAiLCAiKVtbMV1dCiNBc2tzX3NldDEgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzFbNSwgNV0pKSwgIiwgIilbWzFdXQoKcGxvdChNTV9wbmxfc2V0MSwgCiAgICAgdHlwZSA9ICJsIiwgCiAgICAgcGNoID0gMTYsIAogICAgIGNvbCA9ICJibGFjayIsIAogICAgIG1haW4gPSAiUE9TIGluIHNpbSA1IiwgCiAgICAgeGxhYiA9ICJQb3NpdGlvbiBpbiBMaXN0IiwgCiAgICAgeWxhYiA9ICJWYWx1ZSIsIAogICAgIHlsaW0gPSBjKG1pbihjKGFzLm51bWVyaWMoTU1fcG5sX3NldDEpLCBhcy5udW1lcmljKEluZm9ybWVkMV9wbmxfc2V0MSksIGFzLm51bWVyaWMoSW5mb3JtZWQyX3BubF9zZXQxKSwgYXMubnVtZXJpYyhJbmZvcm1lZDNfcG5sX3NldDEpLCBhcy5udW1lcmljKEluZm9ybWVkNF9wbmxfc2V0MSksIGFzLm51bWVyaWMoSW5mb3JtZWQ1X3BubF9zZXQxKSwgYXMubnVtZXJpYyhJbmZvcm1lZDZfcG5sX3NldDEpKSksIAogICAgICAgICAgICAgIG1heChjKGFzLm51bWVyaWMoTU1fcG5sX3NldDEpLCBhcy5udW1lcmljKEluZm9ybWVkMV9wbmxfc2V0MSksIGFzLm51bWVyaWMoSW5mb3JtZWQyX3BubF9zZXQxKSwgYXMubnVtZXJpYyhJbmZvcm1lZDNfcG5sX3NldDEpLCBhcy5udW1lcmljKEluZm9ybWVkNF9wbmxfc2V0MSksIGFzLm51bWVyaWMoSW5mb3JtZWQ1X3BubF9zZXQxKSwgYXMubnVtZXJpYyhJbmZvcm1lZDZfcG5sX3NldDEpKSkpKQoKbGluZXMoSW5mb3JtZWQxX3BubF9zZXQxLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gInJlZCIpCmxpbmVzKEluZm9ybWVkMl9wbmxfc2V0MSwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJncmVlbiIpCmxpbmVzKEluZm9ybWVkM19wbmxfc2V0MSwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJ5ZWxsb3ciKQpsaW5lcyhJbmZvcm1lZDRfcG5sX3NldDEsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAiYmx1ZSIpCmxpbmVzKEluZm9ybWVkNV9wbmxfc2V0MSwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJwdXJwbGUiKQpsaW5lcyhJbmZvcm1lZDZfcG5sX3NldDEsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAib3JhbmdlIikKCiMgQWRkIGxlZ2VuZApsZWdlbmQoImJvdHRvbWxlZnQiLCBsZWdlbmQgPSBjKCJNYXJrZXQgTWFrZXIiLCAiSW5mb3JtZWQgMSIsICJJbmZvcm1lZCAyIiwgIkluZm9ybWVkIDMiLCAiSW5mb3JtZWQgNCIsICJJbmZvcm1lZCA1IiwgIkluZm9ybWVkIDYiKSwgY29sID0gYygiYmxhY2siLCAicmVkIiwgImdyZWVuIiwgInllbGxvdyIsICJibHVlIiwgInB1cnBsZSIsICJvcmFuZ2UiKSwgbHR5ID0gMSwgY2V4ID0gMC44KQpgYGAKCgoKYGBge3J9CiMgSW5pdGlhbGl6ZSBtYXRyaWNlcyB0byBzdG9yZSBhdmVyYWdlcyBmb3IgZWFjaCBwb3NpdGlvbgphdmVyYWdlX01NX3BubCA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKYXZlcmFnZV9JbmZvcm1lZDFfcG5sIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX0luZm9ybWVkMl9wbmwgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfSW5mb3JtZWQzX3BubCA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKYXZlcmFnZV9JbmZvcm1lZDRfcG5sIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX0luZm9ybWVkNV9wbmwgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfSW5mb3JtZWQ2X3BubCA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKCiMgTG9vcCB0aHJvdWdoIGVhY2ggc2ltdWxhdGlvbiAobikKZm9yIChuIGluIDE6MTApIHsKCiAgTU1fcG5sX3NldDEgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzFbbiwgNl0pKSwgIiwgIikKCiAgSW5mb3JtZWQxX3BubF9zZXQxIDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c18xW24sIDhdKSksICIsICIpCiAgCiAgSW5mb3JtZWQyX3BubF9zZXQxIDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c18xW24sIDEwXSkpLCAiLCAiKQogIAogIEluZm9ybWVkM19wbmxfc2V0MSA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfMVtuLCAxMl0pKSwgIiwgIikKICAKICBJbmZvcm1lZDRfcG5sX3NldDEgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzFbbiwgMTRdKSksICIsICIpCiAgCiAgSW5mb3JtZWQ1X3BubF9zZXQxIDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c18xW24sIDE2XSkpLCAiLCAiKQogIAogIEluZm9ybWVkNl9wbmxfc2V0MSA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfMVtuLCAxOF0pKSwgIiwgIikKICAKICAjIExvb3AgdGhyb3VnaCBlYWNoIHBvc2l0aW9uIChpKQogIGZvciAoaSBpbiAxOjEwMCkgewogICAgIyBFeHRyYWN0IFRydWUgYW5kIEV4cGVjdGVkIHZhbHVlcyBmb3IgdGhlIGktdGggcG9zaXRpb24KICAgIE1NX3BubCA8LSBzYXBwbHkoTU1fcG5sX3NldDEsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICBJbmZvcm1lZDFfcG5sIDwtIHNhcHBseShJbmZvcm1lZDFfcG5sX3NldDEsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICBJbmZvcm1lZDJfcG5sIDwtIHNhcHBseShJbmZvcm1lZDJfcG5sX3NldDEsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICBJbmZvcm1lZDNfcG5sIDwtIHNhcHBseShJbmZvcm1lZDNfcG5sX3NldDEsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICBJbmZvcm1lZDRfcG5sIDwtIHNhcHBseShJbmZvcm1lZDRfcG5sX3NldDEsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICBJbmZvcm1lZDVfcG5sIDwtIHNhcHBseShJbmZvcm1lZDVfcG5sX3NldDEsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICBJbmZvcm1lZDZfcG5sIDwtIHNhcHBseShJbmZvcm1lZDZfcG5sX3NldDEsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICAKICAgICMgQ2FsY3VsYXRlIHRoZSBhdmVyYWdlIG9mIFRydWUgYW5kIEV4cGVjdGVkIHZhbHVlcyBmb3IgdGhlIGktdGggcG9zaXRpb24KICAgIGF2ZXJhZ2VfTU1fcG5sW2ksIG5dIDwtIG1lYW4oTU1fcG5sLCBuYS5ybSA9IFRSVUUpCiAgICBhdmVyYWdlX0luZm9ybWVkMV9wbmxbaSwgbl0gPC0gbWVhbihJbmZvcm1lZDFfcG5sLCBuYS5ybSA9IFRSVUUpCiAgICBhdmVyYWdlX0luZm9ybWVkMl9wbmxbaSwgbl0gPC0gbWVhbihJbmZvcm1lZDJfcG5sLCBuYS5ybSA9IFRSVUUpCiAgICBhdmVyYWdlX0luZm9ybWVkM19wbmxbaSwgbl0gPC0gbWVhbihJbmZvcm1lZDNfcG5sLCBuYS5ybSA9IFRSVUUpCiAgICBhdmVyYWdlX0luZm9ybWVkNF9wbmxbaSwgbl0gPC0gbWVhbihJbmZvcm1lZDRfcG5sLCBuYS5ybSA9IFRSVUUpCiAgICBhdmVyYWdlX0luZm9ybWVkNV9wbmxbaSwgbl0gPC0gbWVhbihJbmZvcm1lZDVfcG5sLCBuYS5ybSA9IFRSVUUpCiAgICBhdmVyYWdlX0luZm9ybWVkNl9wbmxbaSwgbl0gPC0gbWVhbihJbmZvcm1lZDZfcG5sLCBuYS5ybSA9IFRSVUUpCiAgfQp9CgojIENhbGN1bGF0ZSB0aGUgb3ZlcmFsbCBhdmVyYWdlIGZvciBlYWNoIHBvc2l0aW9uIGFjcm9zcyBhbGwgc2ltdWxhdGlvbnMKb3ZlcmFsbF9hdmVyYWdlX01NX3BubCA8LSByb3dNZWFucyhhdmVyYWdlX01NX3BubCwgbmEucm0gPSBUUlVFKQpvdmVyYWxsX2F2ZXJhZ2VfSW5mb3JtZWQxX3BubCA8LSByb3dNZWFucyhhdmVyYWdlX0luZm9ybWVkMV9wbmwsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX0luZm9ybWVkMl9wbmwgPC0gcm93TWVhbnMoYXZlcmFnZV9JbmZvcm1lZDJfcG5sLCBuYS5ybSA9IFRSVUUpCm92ZXJhbGxfYXZlcmFnZV9JbmZvcm1lZDNfcG5sIDwtIHJvd01lYW5zKGF2ZXJhZ2VfSW5mb3JtZWQzX3BubCwgbmEucm0gPSBUUlVFKQpvdmVyYWxsX2F2ZXJhZ2VfSW5mb3JtZWQ0X3BubCA8LSByb3dNZWFucyhhdmVyYWdlX0luZm9ybWVkNF9wbmwsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX0luZm9ybWVkNV9wbmwgPC0gcm93TWVhbnMoYXZlcmFnZV9JbmZvcm1lZDVfcG5sLCBuYS5ybSA9IFRSVUUpCm92ZXJhbGxfYXZlcmFnZV9JbmZvcm1lZDZfcG5sIDwtIHJvd01lYW5zKGF2ZXJhZ2VfSW5mb3JtZWQ2X3BubCwgbmEucm0gPSBUUlVFKQoKIyBQbG90IHRoZSBvdmVyYWxsIGF2ZXJhZ2VzCnBsb3Qob3ZlcmFsbF9hdmVyYWdlX01NX3BubCwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJibGFjayIsIG1haW4gPSAiT3ZlcmFsbCBBdmVyYWdlIFBOTCIsIHhsYWIgPSAiUG9zaXRpb24gaW4gTGlzdCIsIHlsYWIgPSAiVmFsdWUiLCB5bGltID0gYyhtaW4oYyhvdmVyYWxsX2F2ZXJhZ2VfTU1fcG5sLCBvdmVyYWxsX2F2ZXJhZ2VfSW5mb3JtZWQxX3BubCwgb3ZlcmFsbF9hdmVyYWdlX0luZm9ybWVkMl9wbmwsIG92ZXJhbGxfYXZlcmFnZV9JbmZvcm1lZDNfcG5sLCBvdmVyYWxsX2F2ZXJhZ2VfSW5mb3JtZWQ0X3BubCwgb3ZlcmFsbF9hdmVyYWdlX0luZm9ybWVkNV9wbmwsIG92ZXJhbGxfYXZlcmFnZV9JbmZvcm1lZDZfcG5sKSksIG1heChjKG92ZXJhbGxfYXZlcmFnZV9NTV9wbmwsIG92ZXJhbGxfYXZlcmFnZV9JbmZvcm1lZDFfcG5sLCBvdmVyYWxsX2F2ZXJhZ2VfSW5mb3JtZWQyX3BubCwgb3ZlcmFsbF9hdmVyYWdlX0luZm9ybWVkM19wbmwsIG92ZXJhbGxfYXZlcmFnZV9JbmZvcm1lZDRfcG5sLCBvdmVyYWxsX2F2ZXJhZ2VfSW5mb3JtZWQ1X3BubCwgb3ZlcmFsbF9hdmVyYWdlX0luZm9ybWVkNl9wbmwpKSkpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9JbmZvcm1lZDFfcG5sLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gInJlZCIpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9JbmZvcm1lZDJfcG5sLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gImdyZWVuIikKbGluZXMob3ZlcmFsbF9hdmVyYWdlX0luZm9ybWVkM19wbmwsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAieWVsbG93IikKbGluZXMob3ZlcmFsbF9hdmVyYWdlX0luZm9ybWVkNF9wbmwsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAiYmx1ZSIpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9JbmZvcm1lZDVfcG5sLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gInB1cnBsZSIpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9JbmZvcm1lZDZfcG5sLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gIm9yYW5nZSIpCgojIEFkZCBsZWdlbmQKbGVnZW5kKCJib3R0b21sZWZ0IiwgbGVnZW5kID0gYygiTWFya2V0IE1ha2VyIiwgIkluZm9ybWVkIDEiLCAiSW5mb3JtZWQgMiIsICJJbmZvcm1lZCAzIiwgIkluZm9ybWVkIDQiLCAiSW5mb3JtZWQgNSIsICJJbmZvcm1lZCA2IiksIGNvbCA9IGMoImJsYWNrIiwgInJlZCIsICJncmVlbiIsICJ5ZWxsb3ciLCAiYmx1ZSIsICJwdXJwbGUiLCAib3JhbmdlIiksIGx0eSA9IDEsIGNleCA9IDAuOCkKYGBgCgpgYGB7cn0KIyBJbml0aWFsaXplIG1hdHJpY2VzIHRvIHN0b3JlIGF2ZXJhZ2VzIGZvciBlYWNoIHBvc2l0aW9uCmF2ZXJhZ2VfTU1fcG9zIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX0luZm9ybWVkMV9wb3MgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfSW5mb3JtZWQyX3BvcyA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKYXZlcmFnZV9JbmZvcm1lZDNfcG9zIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX0luZm9ybWVkNF9wb3MgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfSW5mb3JtZWQ1X3BvcyA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKYXZlcmFnZV9JbmZvcm1lZDZfcG9zIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQoKIyBMb29wIHRocm91Z2ggZWFjaCBzaW11bGF0aW9uIChuKQpmb3IgKG4gaW4gMToxMCkgewoKICBNTV9wb3Nfc2V0MSA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfMVtuLCA3XSkpLCAiLCAiKQoKICBJbmZvcm1lZDFfcG9zX3NldDEgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzFbbiwgOV0pKSwgIiwgIikKICAKICBJbmZvcm1lZDJfcG9zX3NldDEgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzFbbiwgMTFdKSksICIsICIpCiAgCiAgSW5mb3JtZWQzX3Bvc19zZXQxIDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c18xW24sIDEzXSkpLCAiLCAiKQogIAogIEluZm9ybWVkNF9wb3Nfc2V0MSA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfMVtuLCAxNV0pKSwgIiwgIikKICAKICBJbmZvcm1lZDVfcG9zX3NldDEgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzFbbiwgMTddKSksICIsICIpCiAgCiAgSW5mb3JtZWQ2X3Bvc19zZXQxIDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c18xW24sIDE5XSkpLCAiLCAiKQogIAogICMgTG9vcCB0aHJvdWdoIGVhY2ggcG9zaXRpb24gKGkpCiAgZm9yIChpIGluIDE6MTAwKSB7CiAgICAjIEV4dHJhY3QgVHJ1ZSBhbmQgRXhwZWN0ZWQgdmFsdWVzIGZvciB0aGUgaS10aCBwb3NpdGlvbgogICAgTU1fcG9zIDwtIHNhcHBseShNTV9wb3Nfc2V0MSwgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIEluZm9ybWVkMV9wb3MgPC0gc2FwcGx5KEluZm9ybWVkMV9wb3Nfc2V0MSwgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIEluZm9ybWVkMl9wb3MgPC0gc2FwcGx5KEluZm9ybWVkMl9wb3Nfc2V0MSwgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIEluZm9ybWVkM19wb3MgPC0gc2FwcGx5KEluZm9ybWVkM19wb3Nfc2V0MSwgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIEluZm9ybWVkNF9wb3MgPC0gc2FwcGx5KEluZm9ybWVkNF9wb3Nfc2V0MSwgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIEluZm9ybWVkNV9wb3MgPC0gc2FwcGx5KEluZm9ybWVkNV9wb3Nfc2V0MSwgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIEluZm9ybWVkNl9wb3MgPC0gc2FwcGx5KEluZm9ybWVkNl9wb3Nfc2V0MSwgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIAogICAgIyBDYWxjdWxhdGUgdGhlIGF2ZXJhZ2Ugb2YgVHJ1ZSBhbmQgRXhwZWN0ZWQgdmFsdWVzIGZvciB0aGUgaS10aCBwb3NpdGlvbgogICAgYXZlcmFnZV9NTV9wb3NbaSwgbl0gPC0gbWVhbihNTV9wb3MsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfSW5mb3JtZWQxX3Bvc1tpLCBuXSA8LSBtZWFuKEluZm9ybWVkMV9wb3MsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfSW5mb3JtZWQyX3Bvc1tpLCBuXSA8LSBtZWFuKEluZm9ybWVkMl9wb3MsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfSW5mb3JtZWQzX3Bvc1tpLCBuXSA8LSBtZWFuKEluZm9ybWVkM19wb3MsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfSW5mb3JtZWQ0X3Bvc1tpLCBuXSA8LSBtZWFuKEluZm9ybWVkNF9wb3MsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfSW5mb3JtZWQ1X3Bvc1tpLCBuXSA8LSBtZWFuKEluZm9ybWVkNV9wb3MsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfSW5mb3JtZWQ2X3Bvc1tpLCBuXSA8LSBtZWFuKEluZm9ybWVkNl9wb3MsIG5hLnJtID0gVFJVRSkKICB9Cn0KCiMgQ2FsY3VsYXRlIHRoZSBvdmVyYWxsIGF2ZXJhZ2UgZm9yIGVhY2ggcG9zaXRpb24gYWNyb3NzIGFsbCBzaW11bGF0aW9ucwpvdmVyYWxsX2F2ZXJhZ2VfTU1fcG9zIDwtIHJvd01lYW5zKGF2ZXJhZ2VfTU1fcG9zLCBuYS5ybSA9IFRSVUUpCm92ZXJhbGxfYXZlcmFnZV9JbmZvcm1lZDFfcG9zIDwtIHJvd01lYW5zKGF2ZXJhZ2VfSW5mb3JtZWQxX3BvcywgbmEucm0gPSBUUlVFKQpvdmVyYWxsX2F2ZXJhZ2VfSW5mb3JtZWQyX3BvcyA8LSByb3dNZWFucyhhdmVyYWdlX0luZm9ybWVkMl9wb3MsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX0luZm9ybWVkM19wb3MgPC0gcm93TWVhbnMoYXZlcmFnZV9JbmZvcm1lZDNfcG9zLCBuYS5ybSA9IFRSVUUpCm92ZXJhbGxfYXZlcmFnZV9JbmZvcm1lZDRfcG9zIDwtIHJvd01lYW5zKGF2ZXJhZ2VfSW5mb3JtZWQ0X3BvcywgbmEucm0gPSBUUlVFKQpvdmVyYWxsX2F2ZXJhZ2VfSW5mb3JtZWQ1X3BvcyA8LSByb3dNZWFucyhhdmVyYWdlX0luZm9ybWVkNV9wb3MsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX0luZm9ybWVkNl9wb3MgPC0gcm93TWVhbnMoYXZlcmFnZV9JbmZvcm1lZDZfcG9zLCBuYS5ybSA9IFRSVUUpCgojIFBsb3QgdGhlIG92ZXJhbGwgYXZlcmFnZXMKcGxvdChvdmVyYWxsX2F2ZXJhZ2VfTU1fcG9zLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gImJsYWNrIiwgbWFpbiA9ICJPdmVyYWxsIEF2ZXJhZ2UgUG9zaXRpb24iLCB4bGFiID0gIlBvc2l0aW9uIGluIExpc3QiLCB5bGFiID0gIlZhbHVlIiwgeWxpbSA9IGMobWluKGMob3ZlcmFsbF9hdmVyYWdlX01NX3Bvcywgb3ZlcmFsbF9hdmVyYWdlX0luZm9ybWVkMV9wb3MsIG92ZXJhbGxfYXZlcmFnZV9JbmZvcm1lZDJfcG9zLCBvdmVyYWxsX2F2ZXJhZ2VfSW5mb3JtZWQzX3Bvcywgb3ZlcmFsbF9hdmVyYWdlX0luZm9ybWVkNF9wb3MsIG92ZXJhbGxfYXZlcmFnZV9JbmZvcm1lZDVfcG9zLCBvdmVyYWxsX2F2ZXJhZ2VfSW5mb3JtZWQ2X3BvcykpLCBtYXgoYyhvdmVyYWxsX2F2ZXJhZ2VfTU1fcG9zLCBvdmVyYWxsX2F2ZXJhZ2VfSW5mb3JtZWQxX3Bvcywgb3ZlcmFsbF9hdmVyYWdlX0luZm9ybWVkMl9wb3MsIG92ZXJhbGxfYXZlcmFnZV9JbmZvcm1lZDNfcG9zLCBvdmVyYWxsX2F2ZXJhZ2VfSW5mb3JtZWQ0X3Bvcywgb3ZlcmFsbF9hdmVyYWdlX0luZm9ybWVkNV9wb3MsIG92ZXJhbGxfYXZlcmFnZV9JbmZvcm1lZDZfcG9zKSkpKQoKI2ZvciAoaSBpbiBzZXFfYWxvbmcob3ZlcmFsbF9hdmVyYWdlX01NX3BvcykpIHsKICAjaWYgKG92ZXJhbGxfYXZlcmFnZV9NTV9wb3NbaV0gIT0gMCkgewogICAgI3BvaW50cyhpLCBvdmVyYWxsX2F2ZXJhZ2VfTU1fcG9zW2ldLCBjb2wgPSAicmVkIiwgcGNoID0gMTYpCiAgI30KI30KCiNwb2ludHMob3ZlcmFsbF9hdmVyYWdlX01NX3BvcywgY29sID0gInJlZCIsIHBjaCA9IDE2KQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfSW5mb3JtZWQxX3BvcywgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJyZWQiKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfSW5mb3JtZWQyX3BvcywgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJncmVlbiIpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9JbmZvcm1lZDNfcG9zLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gInllbGxvdyIpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9JbmZvcm1lZDRfcG9zLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gImJsdWUiKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfSW5mb3JtZWQ1X3BvcywgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJwdXJwbGUiKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfSW5mb3JtZWQ2X3BvcywgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJvcmFuZ2UiKQoKIyBBZGQgbGVnZW5kCmxlZ2VuZCgiYm90dG9tbGVmdCIsIGxlZ2VuZCA9IGMoIk1hcmtldCBNYWtlciIsICJJbmZvcm1lZCAxIiwgIkluZm9ybWVkIDIiLCAiSW5mb3JtZWQgMyIsICJJbmZvcm1lZCA0IiwgIkluZm9ybWVkIDUiLCAiSW5mb3JtZWQgNiIpLCBjb2wgPSBjKCJibGFjayIsICJyZWQiLCAiZ3JlZW4iLCAieWVsbG93IiwgImJsdWUiLCAicHVycGxlIiwgIm9yYW5nZSIpLCBsdHkgPSAxLCBjZXggPSAwLjgpCmBgYAoKCgojIyBzZXQgMiAoMSBJbmZvcm1lZCArIDEgbm9pc3kgaW5mb3JtZWQgKyAxIG5vaXN5ICsgMSBzdG9jaGFzdGljIG5vaXN5ICsgMSBtciArIDEgbW9tKQoKYGBge3J9CiMgSW5pdGlhbGl6ZSBtYXRyaWNlcyB0byBzdG9yZSBhdmVyYWdlcyBmb3IgZWFjaCBwb3NpdGlvbgphdmVyYWdlX3RydWUgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfZXhwZWN0ZWQgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCgojIExvb3AgdGhyb3VnaCBlYWNoIHNpbXVsYXRpb24gKG4pCmZvciAobiBpbiAxOjEwKSB7CiAgIyBFeHRyYWN0IFRydWUgdmFsdWVzIGZyb20gdGhlIGFnZ3JlZ2F0ZWRfcmVzdWx0c180IGRhdGFmcmFtZQogIFRydWVWYWx1ZXNfc2V0MiA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfMltuLCAyXSkpLCAiLCAiKQogIAogICMgRXh0cmFjdCBFeHBlY3RlZCB2YWx1ZXMgZnJvbSB0aGUgYWdncmVnYXRlZF9yZXN1bHRzXzQgZGF0YWZyYW1lCiAgRXhwZWN0ZWRWYWx1ZXNfc2V0MiA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfMltuLCAzXSkpLCAiLCAiKQogIAogICMgTG9vcCB0aHJvdWdoIGVhY2ggcG9zaXRpb24gKGkpCiAgZm9yIChpIGluIDE6MTAwKSB7CiAgICAjIEV4dHJhY3QgVHJ1ZSBhbmQgRXhwZWN0ZWQgdmFsdWVzIGZvciB0aGUgaS10aCBwb3NpdGlvbgogICAgVHJ1ZV92YWx1ZXMgPC0gc2FwcGx5KFRydWVWYWx1ZXNfc2V0MiwgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIEV4cGVjdGVkX3ZhbHVlcyA8LSBzYXBwbHkoRXhwZWN0ZWRWYWx1ZXNfc2V0MiwgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIAogICAgIyBDYWxjdWxhdGUgdGhlIGF2ZXJhZ2Ugb2YgVHJ1ZSBhbmQgRXhwZWN0ZWQgdmFsdWVzIGZvciB0aGUgaS10aCBwb3NpdGlvbgogICAgYXZlcmFnZV90cnVlW2ksIG5dIDwtIG1lYW4oVHJ1ZV92YWx1ZXMsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfZXhwZWN0ZWRbaSwgbl0gPC0gbWVhbihFeHBlY3RlZF92YWx1ZXMsIG5hLnJtID0gVFJVRSkKICB9Cn0KCiMgQ2FsY3VsYXRlIHRoZSBvdmVyYWxsIGF2ZXJhZ2UgZm9yIGVhY2ggcG9zaXRpb24gYWNyb3NzIGFsbCBzaW11bGF0aW9ucwpvdmVyYWxsX2F2ZXJhZ2VfdHJ1ZSA8LSByb3dNZWFucyhhdmVyYWdlX3RydWUsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX2V4cGVjdGVkIDwtIHJvd01lYW5zKGF2ZXJhZ2VfZXhwZWN0ZWQsIG5hLnJtID0gVFJVRSkKCiMgUGxvdCB0aGUgb3ZlcmFsbCBhdmVyYWdlcwpwbG90KG92ZXJhbGxfYXZlcmFnZV90cnVlLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gImJsdWUiLCBtYWluID0gIk92ZXJhbGwgQXZlcmFnZSBvZiBUcnVlIHZzIEV4cGVjdGVkIFZhbHVlcyIsIHhsYWIgPSAiUG9zaXRpb24gaW4gTGlzdCIsIHlsYWIgPSAiVmFsdWUiLCB5bGltID0gYyhtaW4oYyhvdmVyYWxsX2F2ZXJhZ2VfdHJ1ZSwgb3ZlcmFsbF9hdmVyYWdlX2V4cGVjdGVkKSksIG1heChjKG92ZXJhbGxfYXZlcmFnZV90cnVlLCBvdmVyYWxsX2F2ZXJhZ2VfZXhwZWN0ZWQpKSkpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9leHBlY3RlZCwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJyZWQiKQpsZWdlbmQoInRvcHJpZ2h0IiwgbGVnZW5kID0gYygiVHJ1ZSBWYWx1ZXMiLCAiRXhwZWN0ZWQgVmFsdWVzIiksIGNvbCA9IGMoImJsdWUiLCAicmVkIiksIGx0eSA9IDEsIGNleCA9IDAuOCkKYGBgCgpgYGB7cn0KIyBJbml0aWFsaXplIG1hdHJpY2VzIHRvIHN0b3JlIGF2ZXJhZ2VzIGZvciBlYWNoIHBvc2l0aW9uCmF2ZXJhZ2VfYmlkIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX2FzayA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKCiMgTG9vcCB0aHJvdWdoIGVhY2ggc2ltdWxhdGlvbiAobikKZm9yIChuIGluIDE6MTApIHsKICAjIEV4dHJhY3QgVHJ1ZSB2YWx1ZXMgZnJvbSB0aGUgYWdncmVnYXRlZF9yZXN1bHRzXzQgZGF0YWZyYW1lCiAgQmlkc19zZXQyIDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c18yW24sIDRdKSksICIsICIpCiAgCiAgIyBFeHRyYWN0IEV4cGVjdGVkIHZhbHVlcyBmcm9tIHRoZSBhZ2dyZWdhdGVkX3Jlc3VsdHNfNCBkYXRhZnJhbWUKICBBc2tzX3NldDIgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzJbbiwgNV0pKSwgIiwgIikKICAKICAjIExvb3AgdGhyb3VnaCBlYWNoIHBvc2l0aW9uIChpKQogIGZvciAoaSBpbiAxOjEwMCkgewogICAgIyBFeHRyYWN0IFRydWUgYW5kIEV4cGVjdGVkIHZhbHVlcyBmb3IgdGhlIGktdGggcG9zaXRpb24KICAgIEJpZHMgPC0gc2FwcGx5KEJpZHNfc2V0MiwgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIEFza3MgPC0gc2FwcGx5KEFza3Nfc2V0MiwgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIAogICAgIyBDYWxjdWxhdGUgdGhlIGF2ZXJhZ2Ugb2YgVHJ1ZSBhbmQgRXhwZWN0ZWQgdmFsdWVzIGZvciB0aGUgaS10aCBwb3NpdGlvbgogICAgYXZlcmFnZV9iaWRbaSwgbl0gPC0gbWVhbihCaWRzLCBuYS5ybSA9IFRSVUUpCiAgICBhdmVyYWdlX2Fza1tpLCBuXSA8LSBtZWFuKEFza3MsIG5hLnJtID0gVFJVRSkKICB9Cn0KCiMgQ2FsY3VsYXRlIHRoZSBvdmVyYWxsIGF2ZXJhZ2UgZm9yIGVhY2ggcG9zaXRpb24gYWNyb3NzIGFsbCBzaW11bGF0aW9ucwpvdmVyYWxsX2F2ZXJhZ2VfYmlkIDwtIHJvd01lYW5zKGF2ZXJhZ2VfYmlkLCBuYS5ybSA9IFRSVUUpCm92ZXJhbGxfYXZlcmFnZV9hc2sgPC0gcm93TWVhbnMoYXZlcmFnZV9hc2ssIG5hLnJtID0gVFJVRSkKCiMgUGxvdCB0aGUgb3ZlcmFsbCBhdmVyYWdlcwpwbG90KG92ZXJhbGxfYXZlcmFnZV9iaWQsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAiYmx1ZSIsIG1haW4gPSAiT3ZlcmFsbCBBdmVyYWdlIG9mIEJpZHMgdnMgQXNrcyIsIHhsYWIgPSAiUG9zaXRpb24gaW4gTGlzdCIsIHlsYWIgPSAiVmFsdWUiLCB5bGltID0gYyhtaW4oYyhvdmVyYWxsX2F2ZXJhZ2VfYmlkLCBvdmVyYWxsX2F2ZXJhZ2VfYXNrKSksIG1heChjKG92ZXJhbGxfYXZlcmFnZV9iaWQsIG92ZXJhbGxfYXZlcmFnZV9hc2spKSkpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9hc2ssIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAicmVkIikKbGVnZW5kKCJ0b3ByaWdodCIsIGxlZ2VuZCA9IGMoIkJpZHMiLCAiQXNrcyIpLCBjb2wgPSBjKCJibHVlIiwgInJlZCIpLCBsdHkgPSAxLCBjZXggPSAwLjgpCmBgYAoKYGBge3J9CiMgSW5pdGlhbGl6ZSBtYXRyaWNlcyB0byBzdG9yZSBhdmVyYWdlcyBmb3IgZWFjaCBwb3NpdGlvbgphdmVyYWdlX2JpZCA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKYXZlcmFnZV9hc2sgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCgojIExvb3AgdGhyb3VnaCBlYWNoIHNpbXVsYXRpb24gKG4pCmZvciAobiBpbiAxOjEwKSB7CiAgIyBFeHRyYWN0IFRydWUgdmFsdWVzIGZyb20gdGhlIGFnZ3JlZ2F0ZWRfcmVzdWx0c180IGRhdGFmcmFtZQogIEJpZHNfc2V0MiA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfMltuLCA0XSkpLCAiLCAiKQogIAogICMgRXh0cmFjdCBFeHBlY3RlZCB2YWx1ZXMgZnJvbSB0aGUgYWdncmVnYXRlZF9yZXN1bHRzXzQgZGF0YWZyYW1lCiAgQXNrc19zZXQyIDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c18yW24sIDVdKSksICIsICIpCiAgCiAgIyBMb29wIHRocm91Z2ggZWFjaCBwb3NpdGlvbiAoaSkKICBmb3IgKGkgaW4gMToxMDApIHsKICAgICMgRXh0cmFjdCBUcnVlIGFuZCBFeHBlY3RlZCB2YWx1ZXMgZm9yIHRoZSBpLXRoIHBvc2l0aW9uCiAgICBCaWRzIDwtIHNhcHBseShCaWRzX3NldDIsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICBBc2tzIDwtIHNhcHBseShBc2tzX3NldDIsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICAKICAgICMgQ2FsY3VsYXRlIHRoZSBhdmVyYWdlIG9mIFRydWUgYW5kIEV4cGVjdGVkIHZhbHVlcyBmb3IgdGhlIGktdGggcG9zaXRpb24KICAgIGF2ZXJhZ2VfYmlkW2ksIG5dIDwtIG1lYW4oQmlkcywgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9hc2tbaSwgbl0gPC0gbWVhbihBc2tzLCBuYS5ybSA9IFRSVUUpCiAgfQp9CgojIENhbGN1bGF0ZSB0aGUgb3ZlcmFsbCBhdmVyYWdlIGZvciBlYWNoIHBvc2l0aW9uIGFjcm9zcyBhbGwgc2ltdWxhdGlvbnMKb3ZlcmFsbF9hdmVyYWdlX2JpZCA8LSByb3dNZWFucyhhdmVyYWdlX2JpZCwgbmEucm0gPSBUUlVFKQpvdmVyYWxsX2F2ZXJhZ2VfYXNrIDwtIHJvd01lYW5zKGF2ZXJhZ2VfYXNrLCBuYS5ybSA9IFRSVUUpCgojIyBUcnVlIFZhbHVlCiMgSW5pdGlhbGl6ZSBtYXRyaWNlcyB0byBzdG9yZSBhdmVyYWdlcyBmb3IgZWFjaCBwb3NpdGlvbgphdmVyYWdlX3RydWUgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfZXhwZWN0ZWQgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCgojIExvb3AgdGhyb3VnaCBlYWNoIHNpbXVsYXRpb24gKG4pCmZvciAobiBpbiAxOjEwKSB7CiAgIyBFeHRyYWN0IFRydWUgdmFsdWVzIGZyb20gdGhlIGFnZ3JlZ2F0ZWRfcmVzdWx0c180IGRhdGFmcmFtZQogIFRydWVWYWx1ZXNfc2V0MiA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfMltuLCAyXSkpLCAiLCAiKQogIAogICMgRXh0cmFjdCBFeHBlY3RlZCB2YWx1ZXMgZnJvbSB0aGUgYWdncmVnYXRlZF9yZXN1bHRzXzQgZGF0YWZyYW1lCiAgRXhwZWN0ZWRWYWx1ZXNfc2V0MiA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfMltuLCAzXSkpLCAiLCAiKQogIAogICMgTG9vcCB0aHJvdWdoIGVhY2ggcG9zaXRpb24gKGkpCiAgZm9yIChpIGluIDE6MTAwKSB7CiAgICAjIEV4dHJhY3QgVHJ1ZSBhbmQgRXhwZWN0ZWQgdmFsdWVzIGZvciB0aGUgaS10aCBwb3NpdGlvbgogICAgVHJ1ZV92YWx1ZXMgPC0gc2FwcGx5KFRydWVWYWx1ZXNfc2V0MiwgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIEV4cGVjdGVkX3ZhbHVlcyA8LSBzYXBwbHkoRXhwZWN0ZWRWYWx1ZXNfc2V0MiwgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIAogICAgIyBDYWxjdWxhdGUgdGhlIGF2ZXJhZ2Ugb2YgVHJ1ZSBhbmQgRXhwZWN0ZWQgdmFsdWVzIGZvciB0aGUgaS10aCBwb3NpdGlvbgogICAgYXZlcmFnZV90cnVlW2ksIG5dIDwtIG1lYW4oVHJ1ZV92YWx1ZXMsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfZXhwZWN0ZWRbaSwgbl0gPC0gbWVhbihFeHBlY3RlZF92YWx1ZXMsIG5hLnJtID0gVFJVRSkKICB9Cn0KCiMgQ2FsY3VsYXRlIHRoZSBvdmVyYWxsIGF2ZXJhZ2UgZm9yIGVhY2ggcG9zaXRpb24gYWNyb3NzIGFsbCBzaW11bGF0aW9ucwpvdmVyYWxsX2F2ZXJhZ2VfdHJ1ZSA8LSByb3dNZWFucyhhdmVyYWdlX3RydWUsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX2V4cGVjdGVkIDwtIHJvd01lYW5zKGF2ZXJhZ2VfZXhwZWN0ZWQsIG5hLnJtID0gVFJVRSkKCiMgUGxvdCB0aGUgb3ZlcmFsbCBhdmVyYWdlcwojcGxvdChvdmVyYWxsX2F2ZXJhZ2VfdHJ1ZSwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJibHVlIiwgbWFpbiA9ICJPdmVyYWxsIEF2ZXJhZ2Ugb2YgVHJ1ZSB2cyBFeHBlY3RlZCBWYWx1ZXMiLCB4bGFiID0gIlBvc2l0aW9uIGluIExpc3QiLCB5bGFiID0gIlZhbHVlIiwgeWxpbSA9IGMobWluKGMob3ZlcmFsbF9hdmVyYWdlX3RydWUsIG92ZXJhbGxfYXZlcmFnZV9leHBlY3RlZCkpLCBtYXgoYyhvdmVyYWxsX2F2ZXJhZ2VfdHJ1ZSwgb3ZlcmFsbF9hdmVyYWdlX2V4cGVjdGVkKSkpKQojbGluZXMob3ZlcmFsbF9hdmVyYWdlX2V4cGVjdGVkLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gInJlZCIpCiNsZWdlbmQoInRvcHJpZ2h0IiwgbGVnZW5kID0gYygiVHJ1ZSBWYWx1ZXMiLCAiRXhwZWN0ZWQgVmFsdWVzIiksIGNvbCA9IGMoImJsdWUiLCAicmVkIiksIGx0eSA9IDEsIGNleCA9IDAuOCkKCiMgUGxvdCB0aGUgb3ZlcmFsbCBhdmVyYWdlcwpwbG90KG92ZXJhbGxfYXZlcmFnZV9iaWQsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAiYmx1ZSIsIG1haW4gPSAiT3ZlcmFsbCBBdmVyYWdlIG9mIEJpZHMgdnMgQXNrcyAmIFRydWUgdnMgRXhwZWN0ZWQgVmFsdWVzIiwgeGxhYiA9ICJQb3NpdGlvbiBpbiBMaXN0IiwgeWxhYiA9ICJWYWx1ZSIsIHlsaW0gPSBjKG1pbihjKG92ZXJhbGxfYXZlcmFnZV9iaWQsIG92ZXJhbGxfYXZlcmFnZV9hc2spKSwgbWF4KGMob3ZlcmFsbF9hdmVyYWdlX2JpZCwgb3ZlcmFsbF9hdmVyYWdlX2FzaykpKSkKbGluZXMob3ZlcmFsbF9hdmVyYWdlX2FzaywgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJyZWQiKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfdHJ1ZSwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJncmVlbiIpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9leHBlY3RlZCwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJwdXJwbGUiKQpsZWdlbmQoInRvcHJpZ2h0IiwgbGVnZW5kID0gYygiQmlkcyIsICJBc2tzIiwgIlRydWUgVmFsdWUiLCAiRXhwZWN0ZWQgVmFsdWUiKSwgY29sID0gYygiYmx1ZSIsICJyZWQiLCAiZ3JlZW4iLCAicHVycGxlIiksIGx0eSA9IDEsIGNleCA9IDAuOCkKYGBgCgoKYGBge3J9CiMgSW5pdGlhbGl6ZSBtYXRyaWNlcyB0byBzdG9yZSBhdmVyYWdlcyBmb3IgZWFjaCBwb3NpdGlvbgphdmVyYWdlX01NX3BubCA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKYXZlcmFnZV9JbmZvcm1lZF9wbmwgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfTm9pc3lJbmZvcm1lZF9wbmwgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfTm9pc3lfcG5sIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX1N0b2NoTm9pc3lfcG5sIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX21yX3BubCA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKYXZlcmFnZV9tb21fcG5sIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQoKIyBMb29wIHRocm91Z2ggZWFjaCBzaW11bGF0aW9uIChuKQpmb3IgKG4gaW4gMToxMCkgewoKICBNTV9wbmxfc2V0MiA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfMltuLCA2XSkpLCAiLCAiKQoKICBJbmZvcm1lZF9wbmxfc2V0MiA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfMltuLCA4XSkpLCAiLCAiKQogIAogIE5vaXN5SW5mb3JtZWRfcG5sX3NldDIgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzJbbiwgMTBdKSksICIsICIpCiAgCiAgTm9pc3lfcG5sX3NldDIgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzJbbiwgMTJdKSksICIsICIpCiAgCiAgU3RvY2hOb2lzeV9wbmxfc2V0MiA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfMltuLCAxNF0pKSwgIiwgIikKICAKICBtcl9wbmxfc2V0MiA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfMltuLCAxNl0pKSwgIiwgIikKICAKICBtb21fcG5sX3NldDIgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzJbbiwgMThdKSksICIsICIpCiAgCiAgIyBMb29wIHRocm91Z2ggZWFjaCBwb3NpdGlvbiAoaSkKICBmb3IgKGkgaW4gMToxMDApIHsKICAgICMgRXh0cmFjdCBUcnVlIGFuZCBFeHBlY3RlZCB2YWx1ZXMgZm9yIHRoZSBpLXRoIHBvc2l0aW9uCiAgICBNTV9wbmwgPC0gc2FwcGx5KE1NX3BubF9zZXQyLCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgSW5mb3JtZWRfcG5sIDwtIHNhcHBseShJbmZvcm1lZF9wbmxfc2V0MiwgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIE5vaXN5SW5mb3JtZWRfcG5sIDwtIHNhcHBseShOb2lzeUluZm9ybWVkX3BubF9zZXQyLCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgTm9pc3lfcG5sIDwtIHNhcHBseShOb2lzeV9wbmxfc2V0MiwgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIFN0b2NoTm9pc3lfcG5sIDwtIHNhcHBseShTdG9jaE5vaXN5X3BubF9zZXQyLCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgbXJfcG5sIDwtIHNhcHBseShtcl9wbmxfc2V0MiwgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIG1vbV9wbmwgPC0gc2FwcGx5KG1vbV9wbmxfc2V0MiwgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIAogICAgIyBDYWxjdWxhdGUgdGhlIGF2ZXJhZ2Ugb2YgVHJ1ZSBhbmQgRXhwZWN0ZWQgdmFsdWVzIGZvciB0aGUgaS10aCBwb3NpdGlvbgogICAgYXZlcmFnZV9NTV9wbmxbaSwgbl0gPC0gbWVhbihNTV9wbmwsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfSW5mb3JtZWRfcG5sW2ksIG5dIDwtIG1lYW4oSW5mb3JtZWRfcG5sLCBuYS5ybSA9IFRSVUUpCiAgICBhdmVyYWdlX05vaXN5SW5mb3JtZWRfcG5sW2ksIG5dIDwtIG1lYW4oTm9pc3lJbmZvcm1lZF9wbmwsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfTm9pc3lfcG5sW2ksIG5dIDwtIG1lYW4oTm9pc3lfcG5sLCBuYS5ybSA9IFRSVUUpCiAgICBhdmVyYWdlX1N0b2NoTm9pc3lfcG5sW2ksIG5dIDwtIG1lYW4oU3RvY2hOb2lzeV9wbmwsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfbXJfcG5sW2ksIG5dIDwtIG1lYW4obXJfcG5sLCBuYS5ybSA9IFRSVUUpCiAgICBhdmVyYWdlX21vbV9wbmxbaSwgbl0gPC0gbWVhbihtb21fcG5sLCBuYS5ybSA9IFRSVUUpCiAgfQp9CgojIENhbGN1bGF0ZSB0aGUgb3ZlcmFsbCBhdmVyYWdlIGZvciBlYWNoIHBvc2l0aW9uIGFjcm9zcyBhbGwgc2ltdWxhdGlvbnMKb3ZlcmFsbF9hdmVyYWdlX01NX3BubCA8LSByb3dNZWFucyhhdmVyYWdlX01NX3BubCwgbmEucm0gPSBUUlVFKQpvdmVyYWxsX2F2ZXJhZ2VfSW5mb3JtZWRfcG5sIDwtIHJvd01lYW5zKGF2ZXJhZ2VfSW5mb3JtZWRfcG5sLCBuYS5ybSA9IFRSVUUpCm92ZXJhbGxfYXZlcmFnZV9Ob2lzeUluZm9ybWVkX3BubCA8LSByb3dNZWFucyhhdmVyYWdlX05vaXN5SW5mb3JtZWRfcG5sLCBuYS5ybSA9IFRSVUUpCm92ZXJhbGxfYXZlcmFnZV9Ob2lzeV9wbmwgPC0gcm93TWVhbnMoYXZlcmFnZV9Ob2lzeV9wbmwsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX1N0b2NoTm9pc3lfcG5sIDwtIHJvd01lYW5zKGF2ZXJhZ2VfU3RvY2hOb2lzeV9wbmwsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX21yX3BubCA8LSByb3dNZWFucyhhdmVyYWdlX21yX3BubCwgbmEucm0gPSBUUlVFKQpvdmVyYWxsX2F2ZXJhZ2VfbW9tX3BubCA8LSByb3dNZWFucyhhdmVyYWdlX21vbV9wbmwsIG5hLnJtID0gVFJVRSkKCiMgUGxvdCB0aGUgb3ZlcmFsbCBhdmVyYWdlcwpwbG90KG92ZXJhbGxfYXZlcmFnZV9NTV9wbmwsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAiYmxhY2siLCBtYWluID0gIk92ZXJhbGwgQXZlcmFnZSBQTkwiLCB4bGFiID0gIlBvc2l0aW9uIGluIExpc3QiLCB5bGFiID0gIlZhbHVlIiwgeWxpbSA9IGMobWluKGMob3ZlcmFsbF9hdmVyYWdlX01NX3BubCwgb3ZlcmFsbF9hdmVyYWdlX0luZm9ybWVkX3BubCwgb3ZlcmFsbF9hdmVyYWdlX05vaXN5SW5mb3JtZWRfcG5sLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3lfcG5sLCBvdmVyYWxsX2F2ZXJhZ2VfU3RvY2hOb2lzeV9wbmwsIG92ZXJhbGxfYXZlcmFnZV9tcl9wbmwsIG92ZXJhbGxfYXZlcmFnZV9tb21fcG5sKSksIG1heChjKG92ZXJhbGxfYXZlcmFnZV9NTV9wbmwsIG92ZXJhbGxfYXZlcmFnZV9JbmZvcm1lZF9wbmwsIG92ZXJhbGxfYXZlcmFnZV9Ob2lzeUluZm9ybWVkX3BubCwgb3ZlcmFsbF9hdmVyYWdlX05vaXN5X3BubCwgb3ZlcmFsbF9hdmVyYWdlX1N0b2NoTm9pc3lfcG5sLCBvdmVyYWxsX2F2ZXJhZ2VfbXJfcG5sLCBvdmVyYWxsX2F2ZXJhZ2VfbW9tX3BubCkpKSkKbGluZXMob3ZlcmFsbF9hdmVyYWdlX0luZm9ybWVkX3BubCwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJyZWQiKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfTm9pc3lJbmZvcm1lZF9wbmwsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAiZ3JlZW4iKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfTm9pc3lfcG5sLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gInllbGxvdyIpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9TdG9jaE5vaXN5X3BubCwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJibHVlIikKbGluZXMob3ZlcmFsbF9hdmVyYWdlX21yX3BubCwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJwdXJwbGUiKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfbW9tX3BubCwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJvcmFuZ2UiKQoKIyBBZGQgbGVnZW5kCmxlZ2VuZCgiYm90dG9tbGVmdCIsIGxlZ2VuZCA9IGMoIk1hcmtldCBNYWtlciIsICJJbmZvcm1lZCIsICJOb2lzeSBJbmZvcm1lZCIsICJOb2lzeSIsICJTdG9jaGFzdGljIE5vaXN5IiwgIk1lYW4gUmV2ZXJzaW9uIiwgIk1vbWVudHVtIiksIGNvbCA9IGMoImJsYWNrIiwgInJlZCIsICJncmVlbiIsICJ5ZWxsb3ciLCAiYmx1ZSIsICJwdXJwbGUiLCAib3JhbmdlIiksIGx0eSA9IDEsIGNleCA9IDAuOCkKYGBgCgpgYGB7cn0KIyBJbml0aWFsaXplIG1hdHJpY2VzIHRvIHN0b3JlIGF2ZXJhZ2VzIGZvciBlYWNoIHBvc2l0aW9uCmF2ZXJhZ2VfTU1fcG9zIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX0luZm9ybWVkX3BvcyA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKYXZlcmFnZV9Ob2lzeUluZm9ybWVkX3BvcyA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKYXZlcmFnZV9Ob2lzeV9wb3MgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfU3RvY2hOb2lzeV9wb3MgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfbXJfcG9zIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX21vbV9wb3MgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCgojIExvb3AgdGhyb3VnaCBlYWNoIHNpbXVsYXRpb24gKG4pCmZvciAobiBpbiAxOjEwKSB7CgogIE1NX3Bvc19zZXQyIDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c18yW24sIDddKSksICIsICIpCgogIEluZm9ybWVkX3Bvc19zZXQyIDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c18yW24sIDldKSksICIsICIpCiAgCiAgTm9pc3lJbmZvcm1lZF9wb3Nfc2V0MiA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfMltuLCAxMV0pKSwgIiwgIikKICAKICBOb2lzeV9wb3Nfc2V0MiA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfMltuLCAxM10pKSwgIiwgIikKICAKICBTdG9jaE5vaXN5X3Bvc19zZXQyIDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c18yW24sIDE1XSkpLCAiLCAiKQogIAogIG1yX3Bvc19zZXQyIDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c18yW24sIDE3XSkpLCAiLCAiKQogIAogIG1vbV9wb3Nfc2V0MiA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfMltuLCAxOV0pKSwgIiwgIikKICAKICAjIExvb3AgdGhyb3VnaCBlYWNoIHBvc2l0aW9uIChpKQogIGZvciAoaSBpbiAxOjEwMCkgewogICAgIyBFeHRyYWN0IFRydWUgYW5kIEV4cGVjdGVkIHZhbHVlcyBmb3IgdGhlIGktdGggcG9zaXRpb24KICAgIE1NX3BvcyA8LSBzYXBwbHkoTU1fcG9zX3NldDIsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICBJbmZvcm1lZF9wb3MgPC0gc2FwcGx5KEluZm9ybWVkX3Bvc19zZXQyLCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgTm9pc3lJbmZvcm1lZF9wb3MgPC0gc2FwcGx5KE5vaXN5SW5mb3JtZWRfcG9zX3NldDIsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICBOb2lzeV9wb3MgPC0gc2FwcGx5KE5vaXN5X3Bvc19zZXQyLCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgU3RvY2hOb2lzeV9wb3MgPC0gc2FwcGx5KFN0b2NoTm9pc3lfcG9zX3NldDIsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICBtcl9wb3MgPC0gc2FwcGx5KG1yX3Bvc19zZXQyLCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgbW9tX3BvcyA8LSBzYXBwbHkobW9tX3Bvc19zZXQyLCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgCiAgICAjIENhbGN1bGF0ZSB0aGUgYXZlcmFnZSBvZiBUcnVlIGFuZCBFeHBlY3RlZCB2YWx1ZXMgZm9yIHRoZSBpLXRoIHBvc2l0aW9uCiAgICBhdmVyYWdlX01NX3Bvc1tpLCBuXSA8LSBtZWFuKE1NX3BvcywgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9JbmZvcm1lZF9wb3NbaSwgbl0gPC0gbWVhbihJbmZvcm1lZF9wb3MsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfTm9pc3lJbmZvcm1lZF9wb3NbaSwgbl0gPC0gbWVhbihOb2lzeUluZm9ybWVkX3BvcywgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9Ob2lzeV9wb3NbaSwgbl0gPC0gbWVhbihOb2lzeV9wb3MsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfU3RvY2hOb2lzeV9wb3NbaSwgbl0gPC0gbWVhbihTdG9jaE5vaXN5X3BvcywgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9tcl9wb3NbaSwgbl0gPC0gbWVhbihtcl9wb3MsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfbW9tX3Bvc1tpLCBuXSA8LSBtZWFuKG1vbV9wb3MsIG5hLnJtID0gVFJVRSkKICB9Cn0KCiMgQ2FsY3VsYXRlIHRoZSBvdmVyYWxsIGF2ZXJhZ2UgZm9yIGVhY2ggcG9zaXRpb24gYWNyb3NzIGFsbCBzaW11bGF0aW9ucwpvdmVyYWxsX2F2ZXJhZ2VfTU1fcG9zIDwtIHJvd01lYW5zKGF2ZXJhZ2VfTU1fcG9zLCBuYS5ybSA9IFRSVUUpCm92ZXJhbGxfYXZlcmFnZV9JbmZvcm1lZF9wb3MgPC0gcm93TWVhbnMoYXZlcmFnZV9JbmZvcm1lZF9wb3MsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX05vaXN5SW5mb3JtZWRfcG9zIDwtIHJvd01lYW5zKGF2ZXJhZ2VfTm9pc3lJbmZvcm1lZF9wb3MsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX05vaXN5X3BvcyA8LSByb3dNZWFucyhhdmVyYWdlX05vaXN5X3BvcywgbmEucm0gPSBUUlVFKQpvdmVyYWxsX2F2ZXJhZ2VfU3RvY2hOb2lzeV9wb3MgPC0gcm93TWVhbnMoYXZlcmFnZV9TdG9jaE5vaXN5X3BvcywgbmEucm0gPSBUUlVFKQpvdmVyYWxsX2F2ZXJhZ2VfbXJfcG9zIDwtIHJvd01lYW5zKGF2ZXJhZ2VfbXJfcG9zLCBuYS5ybSA9IFRSVUUpCm92ZXJhbGxfYXZlcmFnZV9tb21fcG9zIDwtIHJvd01lYW5zKGF2ZXJhZ2VfbW9tX3BvcywgbmEucm0gPSBUUlVFKQoKIyBQbG90IHRoZSBvdmVyYWxsIGF2ZXJhZ2VzCnBsb3Qob3ZlcmFsbF9hdmVyYWdlX01NX3BvcywgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJibGFjayIsIG1haW4gPSAiT3ZlcmFsbCBBdmVyYWdlIFBvc2l0aW9uIiwgeGxhYiA9ICJQb3NpdGlvbiBpbiBMaXN0IiwgeWxhYiA9ICJWYWx1ZSIsIHlsaW0gPSBjKG1pbihjKG92ZXJhbGxfYXZlcmFnZV9NTV9wb3MsIG92ZXJhbGxfYXZlcmFnZV9JbmZvcm1lZF9wb3MsIG92ZXJhbGxfYXZlcmFnZV9Ob2lzeUluZm9ybWVkX3Bvcywgb3ZlcmFsbF9hdmVyYWdlX05vaXN5X3Bvcywgb3ZlcmFsbF9hdmVyYWdlX1N0b2NoTm9pc3lfcG9zLCBvdmVyYWxsX2F2ZXJhZ2VfbXJfcG9zLCBvdmVyYWxsX2F2ZXJhZ2VfbW9tX3BvcykpLCBtYXgoYyhvdmVyYWxsX2F2ZXJhZ2VfTU1fcG9zLCBvdmVyYWxsX2F2ZXJhZ2VfSW5mb3JtZWRfcG9zLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3lJbmZvcm1lZF9wb3MsIG92ZXJhbGxfYXZlcmFnZV9Ob2lzeV9wb3MsIG92ZXJhbGxfYXZlcmFnZV9TdG9jaE5vaXN5X3Bvcywgb3ZlcmFsbF9hdmVyYWdlX21yX3Bvcywgb3ZlcmFsbF9hdmVyYWdlX21vbV9wb3MpKSkpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9JbmZvcm1lZF9wb3MsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAicmVkIikKbGluZXMob3ZlcmFsbF9hdmVyYWdlX05vaXN5SW5mb3JtZWRfcG9zLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gImdyZWVuIikKbGluZXMob3ZlcmFsbF9hdmVyYWdlX05vaXN5X3BvcywgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJ5ZWxsb3ciKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfU3RvY2hOb2lzeV9wb3MsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAiYmx1ZSIpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9tcl9wb3MsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAicHVycGxlIikKbGluZXMob3ZlcmFsbF9hdmVyYWdlX21vbV9wb3MsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAib3JhbmdlIikKCiMgQWRkIGxlZ2VuZApsZWdlbmQoImJvdHRvbWxlZnQiLCBsZWdlbmQgPSBjKCJNYXJrZXQgTWFrZXIiLCAiSW5mb3JtZWQiLCAiTm9pc3kgSW5mb3JtZWQiLCAiTm9pc3kiLCAiU3RvY2hhc3RpYyBOb2lzeSIsICJNZWFuIFJldmVyc2lvbiIsICJNb21lbnR1bSIpLCBjb2wgPSBjKCJibGFjayIsICJyZWQiLCAiZ3JlZW4iLCAieWVsbG93IiwgImJsdWUiLCAicHVycGxlIiwgIm9yYW5nZSIpLCBsdHkgPSAxLCBjZXggPSAwLjgpCmBgYAoKCiMjIHNldCAzICgyIHN0b2NoYXN0aWMgbm9pc3kgKyAyIG1yICsgMiBtb20pCgpgYGB7cn0KIyBJbml0aWFsaXplIG1hdHJpY2VzIHRvIHN0b3JlIGF2ZXJhZ2VzIGZvciBlYWNoIHBvc2l0aW9uCmF2ZXJhZ2VfdHJ1ZSA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKYXZlcmFnZV9leHBlY3RlZCA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKCiMgTG9vcCB0aHJvdWdoIGVhY2ggc2ltdWxhdGlvbiAobikKZm9yIChuIGluIDE6MTApIHsKICAjIEV4dHJhY3QgVHJ1ZSB2YWx1ZXMgZnJvbSB0aGUgYWdncmVnYXRlZF9yZXN1bHRzXzQgZGF0YWZyYW1lCiAgVHJ1ZVZhbHVlc19zZXQzIDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c18zW24sIDJdKSksICIsICIpCiAgCiAgIyBFeHRyYWN0IEV4cGVjdGVkIHZhbHVlcyBmcm9tIHRoZSBhZ2dyZWdhdGVkX3Jlc3VsdHNfNCBkYXRhZnJhbWUKICBFeHBlY3RlZFZhbHVlc19zZXQzIDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c18zW24sIDNdKSksICIsICIpCiAgCiAgIyBMb29wIHRocm91Z2ggZWFjaCBwb3NpdGlvbiAoaSkKICBmb3IgKGkgaW4gMToxMDApIHsKICAgICMgRXh0cmFjdCBUcnVlIGFuZCBFeHBlY3RlZCB2YWx1ZXMgZm9yIHRoZSBpLXRoIHBvc2l0aW9uCiAgICBUcnVlX3ZhbHVlcyA8LSBzYXBwbHkoVHJ1ZVZhbHVlc19zZXQzLCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgRXhwZWN0ZWRfdmFsdWVzIDwtIHNhcHBseShFeHBlY3RlZFZhbHVlc19zZXQzLCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgCiAgICAjIENhbGN1bGF0ZSB0aGUgYXZlcmFnZSBvZiBUcnVlIGFuZCBFeHBlY3RlZCB2YWx1ZXMgZm9yIHRoZSBpLXRoIHBvc2l0aW9uCiAgICBhdmVyYWdlX3RydWVbaSwgbl0gPC0gbWVhbihUcnVlX3ZhbHVlcywgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9leHBlY3RlZFtpLCBuXSA8LSBtZWFuKEV4cGVjdGVkX3ZhbHVlcywgbmEucm0gPSBUUlVFKQogIH0KfQoKIyBDYWxjdWxhdGUgdGhlIG92ZXJhbGwgYXZlcmFnZSBmb3IgZWFjaCBwb3NpdGlvbiBhY3Jvc3MgYWxsIHNpbXVsYXRpb25zCm92ZXJhbGxfYXZlcmFnZV90cnVlIDwtIHJvd01lYW5zKGF2ZXJhZ2VfdHJ1ZSwgbmEucm0gPSBUUlVFKQpvdmVyYWxsX2F2ZXJhZ2VfZXhwZWN0ZWQgPC0gcm93TWVhbnMoYXZlcmFnZV9leHBlY3RlZCwgbmEucm0gPSBUUlVFKQoKIyBQbG90IHRoZSBvdmVyYWxsIGF2ZXJhZ2VzCnBsb3Qob3ZlcmFsbF9hdmVyYWdlX3RydWUsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAiYmx1ZSIsIG1haW4gPSAiT3ZlcmFsbCBBdmVyYWdlIG9mIFRydWUgdnMgRXhwZWN0ZWQgVmFsdWVzIiwgeGxhYiA9ICJQb3NpdGlvbiBpbiBMaXN0IiwgeWxhYiA9ICJWYWx1ZSIsIHlsaW0gPSBjKG1pbihjKG92ZXJhbGxfYXZlcmFnZV90cnVlLCBvdmVyYWxsX2F2ZXJhZ2VfZXhwZWN0ZWQpKSwgbWF4KGMob3ZlcmFsbF9hdmVyYWdlX3RydWUsIG92ZXJhbGxfYXZlcmFnZV9leHBlY3RlZCkpKSkKbGluZXMob3ZlcmFsbF9hdmVyYWdlX2V4cGVjdGVkLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gInJlZCIpCmxlZ2VuZCgidG9wcmlnaHQiLCBsZWdlbmQgPSBjKCJUcnVlIFZhbHVlcyIsICJFeHBlY3RlZCBWYWx1ZXMiKSwgY29sID0gYygiYmx1ZSIsICJyZWQiKSwgbHR5ID0gMSwgY2V4ID0gMC44KQpgYGAKCgpgYGB7cn0KIyBJbml0aWFsaXplIG1hdHJpY2VzIHRvIHN0b3JlIGF2ZXJhZ2VzIGZvciBlYWNoIHBvc2l0aW9uCmF2ZXJhZ2VfYmlkIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX2FzayA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKCiMgTG9vcCB0aHJvdWdoIGVhY2ggc2ltdWxhdGlvbiAobikKZm9yIChuIGluIDE6MTApIHsKICAjIEV4dHJhY3QgVHJ1ZSB2YWx1ZXMgZnJvbSB0aGUgYWdncmVnYXRlZF9yZXN1bHRzXzQgZGF0YWZyYW1lCiAgQmlkc19zZXQzIDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c18zW24sIDRdKSksICIsICIpCiAgCiAgIyBFeHRyYWN0IEV4cGVjdGVkIHZhbHVlcyBmcm9tIHRoZSBhZ2dyZWdhdGVkX3Jlc3VsdHNfNCBkYXRhZnJhbWUKICBBc2tzX3NldDMgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzNbbiwgNV0pKSwgIiwgIikKICAKICAjIExvb3AgdGhyb3VnaCBlYWNoIHBvc2l0aW9uIChpKQogIGZvciAoaSBpbiAxOjEwMCkgewogICAgIyBFeHRyYWN0IFRydWUgYW5kIEV4cGVjdGVkIHZhbHVlcyBmb3IgdGhlIGktdGggcG9zaXRpb24KICAgIEJpZHMgPC0gc2FwcGx5KEJpZHNfc2V0MywgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIEFza3MgPC0gc2FwcGx5KEFza3Nfc2V0MywgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIAogICAgIyBDYWxjdWxhdGUgdGhlIGF2ZXJhZ2Ugb2YgVHJ1ZSBhbmQgRXhwZWN0ZWQgdmFsdWVzIGZvciB0aGUgaS10aCBwb3NpdGlvbgogICAgYXZlcmFnZV9iaWRbaSwgbl0gPC0gbWVhbihCaWRzLCBuYS5ybSA9IFRSVUUpCiAgICBhdmVyYWdlX2Fza1tpLCBuXSA8LSBtZWFuKEFza3MsIG5hLnJtID0gVFJVRSkKICB9Cn0KCiMgQ2FsY3VsYXRlIHRoZSBvdmVyYWxsIGF2ZXJhZ2UgZm9yIGVhY2ggcG9zaXRpb24gYWNyb3NzIGFsbCBzaW11bGF0aW9ucwpvdmVyYWxsX2F2ZXJhZ2VfYmlkIDwtIHJvd01lYW5zKGF2ZXJhZ2VfYmlkLCBuYS5ybSA9IFRSVUUpCm92ZXJhbGxfYXZlcmFnZV9hc2sgPC0gcm93TWVhbnMoYXZlcmFnZV9hc2ssIG5hLnJtID0gVFJVRSkKCiMgUGxvdCB0aGUgb3ZlcmFsbCBhdmVyYWdlcwpwbG90KG92ZXJhbGxfYXZlcmFnZV9iaWQsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAiYmx1ZSIsIG1haW4gPSAiT3ZlcmFsbCBBdmVyYWdlIG9mIEJpZHMgdnMgQXNrcyIsIHhsYWIgPSAiUG9zaXRpb24gaW4gTGlzdCIsIHlsYWIgPSAiVmFsdWUiLCB5bGltID0gYyhtaW4oYyhvdmVyYWxsX2F2ZXJhZ2VfYmlkLCBvdmVyYWxsX2F2ZXJhZ2VfYXNrKSksIG1heChjKG92ZXJhbGxfYXZlcmFnZV9iaWQsIG92ZXJhbGxfYXZlcmFnZV9hc2spKSkpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9hc2ssIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAicmVkIikKbGVnZW5kKCJ0b3ByaWdodCIsIGxlZ2VuZCA9IGMoIkJpZHMiLCAiQXNrcyIpLCBjb2wgPSBjKCJibHVlIiwgInJlZCIpLCBsdHkgPSAxLCBjZXggPSAwLjgpCmBgYAoKYGBge3J9CiMgSW5pdGlhbGl6ZSBtYXRyaWNlcyB0byBzdG9yZSBhdmVyYWdlcyBmb3IgZWFjaCBwb3NpdGlvbgphdmVyYWdlX2JpZCA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKYXZlcmFnZV9hc2sgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCgojIExvb3AgdGhyb3VnaCBlYWNoIHNpbXVsYXRpb24gKG4pCmZvciAobiBpbiAxOjEwKSB7CiAgIyBFeHRyYWN0IFRydWUgdmFsdWVzIGZyb20gdGhlIGFnZ3JlZ2F0ZWRfcmVzdWx0c180IGRhdGFmcmFtZQogIEJpZHNfc2V0MyA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfM1tuLCA0XSkpLCAiLCAiKQogIAogICMgRXh0cmFjdCBFeHBlY3RlZCB2YWx1ZXMgZnJvbSB0aGUgYWdncmVnYXRlZF9yZXN1bHRzXzQgZGF0YWZyYW1lCiAgQXNrc19zZXQzIDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c18zW24sIDVdKSksICIsICIpCiAgCiAgIyBMb29wIHRocm91Z2ggZWFjaCBwb3NpdGlvbiAoaSkKICBmb3IgKGkgaW4gMToxMDApIHsKICAgICMgRXh0cmFjdCBUcnVlIGFuZCBFeHBlY3RlZCB2YWx1ZXMgZm9yIHRoZSBpLXRoIHBvc2l0aW9uCiAgICBCaWRzIDwtIHNhcHBseShCaWRzX3NldDMsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICBBc2tzIDwtIHNhcHBseShBc2tzX3NldDMsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICAKICAgICMgQ2FsY3VsYXRlIHRoZSBhdmVyYWdlIG9mIFRydWUgYW5kIEV4cGVjdGVkIHZhbHVlcyBmb3IgdGhlIGktdGggcG9zaXRpb24KICAgIGF2ZXJhZ2VfYmlkW2ksIG5dIDwtIG1lYW4oQmlkcywgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9hc2tbaSwgbl0gPC0gbWVhbihBc2tzLCBuYS5ybSA9IFRSVUUpCiAgfQp9CgojIENhbGN1bGF0ZSB0aGUgb3ZlcmFsbCBhdmVyYWdlIGZvciBlYWNoIHBvc2l0aW9uIGFjcm9zcyBhbGwgc2ltdWxhdGlvbnMKb3ZlcmFsbF9hdmVyYWdlX2JpZCA8LSByb3dNZWFucyhhdmVyYWdlX2JpZCwgbmEucm0gPSBUUlVFKQpvdmVyYWxsX2F2ZXJhZ2VfYXNrIDwtIHJvd01lYW5zKGF2ZXJhZ2VfYXNrLCBuYS5ybSA9IFRSVUUpCgojIyBUcnVlIFZhbHVlCiMgSW5pdGlhbGl6ZSBtYXRyaWNlcyB0byBzdG9yZSBhdmVyYWdlcyBmb3IgZWFjaCBwb3NpdGlvbgphdmVyYWdlX3RydWUgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfZXhwZWN0ZWQgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCgojIExvb3AgdGhyb3VnaCBlYWNoIHNpbXVsYXRpb24gKG4pCmZvciAobiBpbiAxOjEwKSB7CiAgIyBFeHRyYWN0IFRydWUgdmFsdWVzIGZyb20gdGhlIGFnZ3JlZ2F0ZWRfcmVzdWx0c180IGRhdGFmcmFtZQogIFRydWVWYWx1ZXNfc2V0MyA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfM1tuLCAyXSkpLCAiLCAiKQogIAogICMgRXh0cmFjdCBFeHBlY3RlZCB2YWx1ZXMgZnJvbSB0aGUgYWdncmVnYXRlZF9yZXN1bHRzXzQgZGF0YWZyYW1lCiAgRXhwZWN0ZWRWYWx1ZXNfc2V0MyA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfM1tuLCAzXSkpLCAiLCAiKQogIAogICMgTG9vcCB0aHJvdWdoIGVhY2ggcG9zaXRpb24gKGkpCiAgZm9yIChpIGluIDE6MTAwKSB7CiAgICAjIEV4dHJhY3QgVHJ1ZSBhbmQgRXhwZWN0ZWQgdmFsdWVzIGZvciB0aGUgaS10aCBwb3NpdGlvbgogICAgVHJ1ZV92YWx1ZXMgPC0gc2FwcGx5KFRydWVWYWx1ZXNfc2V0MywgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIEV4cGVjdGVkX3ZhbHVlcyA8LSBzYXBwbHkoRXhwZWN0ZWRWYWx1ZXNfc2V0MywgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIAogICAgIyBDYWxjdWxhdGUgdGhlIGF2ZXJhZ2Ugb2YgVHJ1ZSBhbmQgRXhwZWN0ZWQgdmFsdWVzIGZvciB0aGUgaS10aCBwb3NpdGlvbgogICAgYXZlcmFnZV90cnVlW2ksIG5dIDwtIG1lYW4oVHJ1ZV92YWx1ZXMsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfZXhwZWN0ZWRbaSwgbl0gPC0gbWVhbihFeHBlY3RlZF92YWx1ZXMsIG5hLnJtID0gVFJVRSkKICB9Cn0KCiMgQ2FsY3VsYXRlIHRoZSBvdmVyYWxsIGF2ZXJhZ2UgZm9yIGVhY2ggcG9zaXRpb24gYWNyb3NzIGFsbCBzaW11bGF0aW9ucwpvdmVyYWxsX2F2ZXJhZ2VfdHJ1ZSA8LSByb3dNZWFucyhhdmVyYWdlX3RydWUsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX2V4cGVjdGVkIDwtIHJvd01lYW5zKGF2ZXJhZ2VfZXhwZWN0ZWQsIG5hLnJtID0gVFJVRSkKCiMgUGxvdCB0aGUgb3ZlcmFsbCBhdmVyYWdlcwojcGxvdChvdmVyYWxsX2F2ZXJhZ2VfdHJ1ZSwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJibHVlIiwgbWFpbiA9ICJPdmVyYWxsIEF2ZXJhZ2Ugb2YgVHJ1ZSB2cyBFeHBlY3RlZCBWYWx1ZXMiLCB4bGFiID0gIlBvc2l0aW9uIGluIExpc3QiLCB5bGFiID0gIlZhbHVlIiwgeWxpbSA9IGMobWluKGMob3ZlcmFsbF9hdmVyYWdlX3RydWUsIG92ZXJhbGxfYXZlcmFnZV9leHBlY3RlZCkpLCBtYXgoYyhvdmVyYWxsX2F2ZXJhZ2VfdHJ1ZSwgb3ZlcmFsbF9hdmVyYWdlX2V4cGVjdGVkKSkpKQojbGluZXMob3ZlcmFsbF9hdmVyYWdlX2V4cGVjdGVkLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gInJlZCIpCiNsZWdlbmQoInRvcHJpZ2h0IiwgbGVnZW5kID0gYygiVHJ1ZSBWYWx1ZXMiLCAiRXhwZWN0ZWQgVmFsdWVzIiksIGNvbCA9IGMoImJsdWUiLCAicmVkIiksIGx0eSA9IDEsIGNleCA9IDAuOCkKCiMgUGxvdCB0aGUgb3ZlcmFsbCBhdmVyYWdlcwpwbG90KG92ZXJhbGxfYXZlcmFnZV9iaWQsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAiYmx1ZSIsIG1haW4gPSAiT3ZlcmFsbCBBdmVyYWdlIG9mIEJpZHMgdnMgQXNrcyAmIFRydWUgdnMgRXhwZWN0ZWQgVmFsdWVzIiwgeGxhYiA9ICJQb3NpdGlvbiBpbiBMaXN0IiwgeWxhYiA9ICJWYWx1ZSIsIHlsaW0gPSBjKG1pbihjKG92ZXJhbGxfYXZlcmFnZV9iaWQsIG92ZXJhbGxfYXZlcmFnZV9hc2ssIG92ZXJhbGxfYXZlcmFnZV90cnVlLCBvdmVyYWxsX2F2ZXJhZ2VfZXhwZWN0ZWQpKSwgbWF4KGMob3ZlcmFsbF9hdmVyYWdlX2JpZCwgb3ZlcmFsbF9hdmVyYWdlX2Fzaywgb3ZlcmFsbF9hdmVyYWdlX3RydWUsIG92ZXJhbGxfYXZlcmFnZV9leHBlY3RlZCkpKSkKbGluZXMob3ZlcmFsbF9hdmVyYWdlX2FzaywgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJyZWQiKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfdHJ1ZSwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJncmVlbiIpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9leHBlY3RlZCwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJwdXJwbGUiKQpsZWdlbmQoImJvdHRvbWxlZnQiLCBsZWdlbmQgPSBjKCJCaWRzIiwgIkFza3MiLCAiVHJ1ZSBWYWx1ZSIsICJFeHBlY3RlZCBWYWx1ZSIpLCBjb2wgPSBjKCJibHVlIiwgInJlZCIsICJncmVlbiIsICJwdXJwbGUiKSwgbHR5ID0gMSwgY2V4ID0gMC44KQpgYGAKCgpgYGB7cn0KIyBJbml0aWFsaXplIG1hdHJpY2VzIHRvIHN0b3JlIGF2ZXJhZ2VzIGZvciBlYWNoIHBvc2l0aW9uCmF2ZXJhZ2VfTU1fcG5sIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX1N0b2NoTm9pc3kxX3BubCA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKYXZlcmFnZV9TdG9jaE5vaXN5Ml9wbmwgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfbXIxX3BubCA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKYXZlcmFnZV9tcjJfcG5sIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX21vbTFfcG5sIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX21vbTJfcG5sIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQoKIyBMb29wIHRocm91Z2ggZWFjaCBzaW11bGF0aW9uIChuKQpmb3IgKG4gaW4gMToxMCkgewoKICBNTV9wbmxfc2V0MyA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfM1tuLCA2XSkpLCAiLCAiKQoKICBTdG9jaE5vaXN5MV9wbmxfc2V0MyA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfM1tuLCA4XSkpLCAiLCAiKQogIAogIFN0b2NoTm9pc3kyX3BubF9zZXQzIDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c18zW24sIDEwXSkpLCAiLCAiKQogIAogIG1yMV9wbmxfc2V0MyA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfM1tuLCAxMl0pKSwgIiwgIikKICAKICBtcjJfcG5sX3NldDMgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzNbbiwgMTRdKSksICIsICIpCiAgCiAgbW9tMV9wbmxfc2V0MyA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfM1tuLCAxNl0pKSwgIiwgIikKICAKICBtb20yX3BubF9zZXQzIDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c18zW24sIDE4XSkpLCAiLCAiKQogIAogICMgTG9vcCB0aHJvdWdoIGVhY2ggcG9zaXRpb24gKGkpCiAgZm9yIChpIGluIDE6MTAwKSB7CiAgICAjIEV4dHJhY3QgVHJ1ZSBhbmQgRXhwZWN0ZWQgdmFsdWVzIGZvciB0aGUgaS10aCBwb3NpdGlvbgogICAgTU1fcG5sIDwtIHNhcHBseShNTV9wbmxfc2V0MywgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIFN0b2NoTm9pc3kxX3BubCA8LSBzYXBwbHkoU3RvY2hOb2lzeTFfcG5sX3NldDMsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICBTdG9jaE5vaXN5Ml9wbmwgPC0gc2FwcGx5KFN0b2NoTm9pc3kyX3BubF9zZXQzLCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgbXIxX3BubCA8LSBzYXBwbHkobXIxX3BubF9zZXQzLCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgbXIyX3BubCA8LSBzYXBwbHkobXIyX3BubF9zZXQzLCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgbW9tMV9wbmwgPC0gc2FwcGx5KG1vbTFfcG5sX3NldDMsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICBtb20yX3BubCA8LSBzYXBwbHkobW9tMl9wbmxfc2V0MywgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIAogICAgIyBDYWxjdWxhdGUgdGhlIGF2ZXJhZ2Ugb2YgVHJ1ZSBhbmQgRXhwZWN0ZWQgdmFsdWVzIGZvciB0aGUgaS10aCBwb3NpdGlvbgogICAgYXZlcmFnZV9NTV9wbmxbaSwgbl0gPC0gbWVhbihNTV9wbmwsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfU3RvY2hOb2lzeTFfcG5sW2ksIG5dIDwtIG1lYW4oU3RvY2hOb2lzeTFfcG5sLCBuYS5ybSA9IFRSVUUpCiAgICBhdmVyYWdlX1N0b2NoTm9pc3kyX3BubFtpLCBuXSA8LSBtZWFuKFN0b2NoTm9pc3kyX3BubCwgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9tcjFfcG5sW2ksIG5dIDwtIG1lYW4obXIxX3BubCwgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9tcjJfcG5sW2ksIG5dIDwtIG1lYW4obXIyX3BubCwgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9tb20xX3BubFtpLCBuXSA8LSBtZWFuKG1vbTFfcG5sLCBuYS5ybSA9IFRSVUUpCiAgICBhdmVyYWdlX21vbTJfcG5sW2ksIG5dIDwtIG1lYW4obW9tMl9wbmwsIG5hLnJtID0gVFJVRSkKICB9Cn0KCiMgQ2FsY3VsYXRlIHRoZSBvdmVyYWxsIGF2ZXJhZ2UgZm9yIGVhY2ggcG9zaXRpb24gYWNyb3NzIGFsbCBzaW11bGF0aW9ucwpvdmVyYWxsX2F2ZXJhZ2VfTU1fcG5sIDwtIHJvd01lYW5zKGF2ZXJhZ2VfTU1fcG5sLCBuYS5ybSA9IFRSVUUpCm92ZXJhbGxfYXZlcmFnZV9TdG9jaE5vaXN5MV9wbmwgPC0gcm93TWVhbnMoYXZlcmFnZV9TdG9jaE5vaXN5MV9wbmwsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX1N0b2NoTm9pc3kyX3BubCA8LSByb3dNZWFucyhhdmVyYWdlX1N0b2NoTm9pc3kyX3BubCwgbmEucm0gPSBUUlVFKQpvdmVyYWxsX2F2ZXJhZ2VfbXIxX3BubCA8LSByb3dNZWFucyhhdmVyYWdlX21yMV9wbmwsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX21yMl9wbmwgPC0gcm93TWVhbnMoYXZlcmFnZV9tcjJfcG5sLCBuYS5ybSA9IFRSVUUpCm92ZXJhbGxfYXZlcmFnZV9tb20xX3BubCA8LSByb3dNZWFucyhhdmVyYWdlX21vbTFfcG5sLCBuYS5ybSA9IFRSVUUpCm92ZXJhbGxfYXZlcmFnZV9tb20yX3BubCA8LSByb3dNZWFucyhhdmVyYWdlX21vbTJfcG5sLCBuYS5ybSA9IFRSVUUpCgojIFBsb3QgdGhlIG92ZXJhbGwgYXZlcmFnZXMKcGxvdChvdmVyYWxsX2F2ZXJhZ2VfTU1fcG5sLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gImJsYWNrIiwgbWFpbiA9ICJPdmVyYWxsIEF2ZXJhZ2UgUE5MIiwgeGxhYiA9ICJQb3NpdGlvbiBpbiBMaXN0IiwgeWxhYiA9ICJWYWx1ZSIsIHlsaW0gPSBjKG1pbihjKG92ZXJhbGxfYXZlcmFnZV9NTV9wbmwsIG92ZXJhbGxfYXZlcmFnZV9TdG9jaE5vaXN5MV9wbmwsIG92ZXJhbGxfYXZlcmFnZV9TdG9jaE5vaXN5Ml9wbmwsIG92ZXJhbGxfYXZlcmFnZV9tcjFfcG5sLCBvdmVyYWxsX2F2ZXJhZ2VfbXIyX3BubCwgb3ZlcmFsbF9hdmVyYWdlX21vbTFfcG5sLCBvdmVyYWxsX2F2ZXJhZ2VfbW9tMl9wbmwpKSwgbWF4KGMob3ZlcmFsbF9hdmVyYWdlX01NX3BubCwgb3ZlcmFsbF9hdmVyYWdlX1N0b2NoTm9pc3kxX3BubCwgb3ZlcmFsbF9hdmVyYWdlX1N0b2NoTm9pc3kyX3BubCwgb3ZlcmFsbF9hdmVyYWdlX21yMV9wbmwsIG92ZXJhbGxfYXZlcmFnZV9tcjJfcG5sLCBvdmVyYWxsX2F2ZXJhZ2VfbW9tMV9wbmwsIG92ZXJhbGxfYXZlcmFnZV9tb20yX3BubCkpKSkKbGluZXMob3ZlcmFsbF9hdmVyYWdlX1N0b2NoTm9pc3kxX3BubCwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJyZWQiKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfU3RvY2hOb2lzeTJfcG5sLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gImdyZWVuIikKbGluZXMob3ZlcmFsbF9hdmVyYWdlX21yMV9wbmwsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAieWVsbG93IikKbGluZXMob3ZlcmFsbF9hdmVyYWdlX21yMl9wbmwsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAiYmx1ZSIpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9tb20xX3BubCwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJwdXJwbGUiKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfbW9tMl9wbmwsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAib3JhbmdlIikKCiMgQWRkIGxlZ2VuZApsZWdlbmQoImJvdHRvbWxlZnQiLCBsZWdlbmQgPSBjKCJNYXJrZXQgTWFrZXIiLCAiU3RvY2hhc3RpYyBOb2lzeSAxIiwgIlN0b2NoYXN0aWMgTm9pc3kgMiIsICJNZWFuIFJldmVyc2lvbiAxIiwgIk1lYW4gUmV2ZXJzaW9uIDIiLCAiTW9tZW50dW0gMSIsICJNb21lbnR1bSAyIiksIGNvbCA9IGMoImJsYWNrIiwgInJlZCIsICJncmVlbiIsICJ5ZWxsb3ciLCAiYmx1ZSIsICJwdXJwbGUiLCAib3JhbmdlIiksIGx0eSA9IDEsIGNleCA9IDAuOCkKYGBgCgoKYGBge3J9CiMgSW5pdGlhbGl6ZSBtYXRyaWNlcyB0byBzdG9yZSBhdmVyYWdlcyBmb3IgZWFjaCBwb3NpdGlvbgphdmVyYWdlX01NX3BvcyA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKYXZlcmFnZV9TdG9jaE5vaXN5MV9wb3MgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfU3RvY2hOb2lzeTJfcG9zIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX21yMV9wb3MgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfbXIyX3BvcyA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKYXZlcmFnZV9tb20xX3BvcyA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKYXZlcmFnZV9tb20yX3BvcyA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKCiMgTG9vcCB0aHJvdWdoIGVhY2ggc2ltdWxhdGlvbiAobikKZm9yIChuIGluIDE6MTApIHsKCiAgTU1fcG9zX3NldDMgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzNbbiwgN10pKSwgIiwgIikKCiAgU3RvY2hOb2lzeTFfcG9zX3NldDMgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzNbbiwgOV0pKSwgIiwgIikKICAKICBTdG9jaE5vaXN5Ml9wb3Nfc2V0MyA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfM1tuLCAxMV0pKSwgIiwgIikKICAKICBtcjFfcG9zX3NldDMgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzNbbiwgMTJdKSksICIsICIpCiAgCiAgbXIyX3Bvc19zZXQzIDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c18zW24sIDE1XSkpLCAiLCAiKQogIAogIG1vbTFfcG9zX3NldDMgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzNbbiwgMTddKSksICIsICIpCiAgCiAgbW9tMl9wb3Nfc2V0MyA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfM1tuLCAxOV0pKSwgIiwgIikKICAKICAjIExvb3AgdGhyb3VnaCBlYWNoIHBvc2l0aW9uIChpKQogIGZvciAoaSBpbiAxOjEwMCkgewogICAgIyBFeHRyYWN0IFRydWUgYW5kIEV4cGVjdGVkIHZhbHVlcyBmb3IgdGhlIGktdGggcG9zaXRpb24KICAgIE1NX3BvcyA8LSBzYXBwbHkoTU1fcG9zX3NldDMsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICBTdG9jaE5vaXN5MV9wb3MgPC0gc2FwcGx5KFN0b2NoTm9pc3kxX3Bvc19zZXQzLCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgU3RvY2hOb2lzeTJfcG9zIDwtIHNhcHBseShTdG9jaE5vaXN5Ml9wb3Nfc2V0MywgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIG1yMV9wb3MgPC0gc2FwcGx5KG1yMV9wb3Nfc2V0MywgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIG1yMl9wb3MgPC0gc2FwcGx5KG1yMl9wb3Nfc2V0MywgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIG1vbTFfcG9zIDwtIHNhcHBseShtb20xX3Bvc19zZXQzLCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgbW9tMl9wb3MgPC0gc2FwcGx5KG1vbTJfcG9zX3NldDMsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICAKICAgICMgQ2FsY3VsYXRlIHRoZSBhdmVyYWdlIG9mIFRydWUgYW5kIEV4cGVjdGVkIHZhbHVlcyBmb3IgdGhlIGktdGggcG9zaXRpb24KICAgIGF2ZXJhZ2VfTU1fcG9zW2ksIG5dIDwtIG1lYW4oTU1fcG9zLCBuYS5ybSA9IFRSVUUpCiAgICBhdmVyYWdlX1N0b2NoTm9pc3kxX3Bvc1tpLCBuXSA8LSBtZWFuKFN0b2NoTm9pc3kxX3BvcywgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9TdG9jaE5vaXN5Ml9wb3NbaSwgbl0gPC0gbWVhbihTdG9jaE5vaXN5Ml9wb3MsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfbXIxX3Bvc1tpLCBuXSA8LSBtZWFuKG1yMV9wb3MsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfbXIyX3Bvc1tpLCBuXSA8LSBtZWFuKG1yMl9wb3MsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfbW9tMV9wb3NbaSwgbl0gPC0gbWVhbihtb20xX3BvcywgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9tb20yX3Bvc1tpLCBuXSA8LSBtZWFuKG1vbTJfcG9zLCBuYS5ybSA9IFRSVUUpCiAgfQp9CgojIENhbGN1bGF0ZSB0aGUgb3ZlcmFsbCBhdmVyYWdlIGZvciBlYWNoIHBvc2l0aW9uIGFjcm9zcyBhbGwgc2ltdWxhdGlvbnMKb3ZlcmFsbF9hdmVyYWdlX01NX3BvcyA8LSByb3dNZWFucyhhdmVyYWdlX01NX3BvcywgbmEucm0gPSBUUlVFKQpvdmVyYWxsX2F2ZXJhZ2VfU3RvY2hOb2lzeTFfcG9zIDwtIHJvd01lYW5zKGF2ZXJhZ2VfU3RvY2hOb2lzeTFfcG9zLCBuYS5ybSA9IFRSVUUpCm92ZXJhbGxfYXZlcmFnZV9TdG9jaE5vaXN5Ml9wb3MgPC0gcm93TWVhbnMoYXZlcmFnZV9TdG9jaE5vaXN5Ml9wb3MsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX21yMV9wb3MgPC0gcm93TWVhbnMoYXZlcmFnZV9tcjFfcG9zLCBuYS5ybSA9IFRSVUUpCm92ZXJhbGxfYXZlcmFnZV9tcjJfcG9zIDwtIHJvd01lYW5zKGF2ZXJhZ2VfbXIyX3BvcywgbmEucm0gPSBUUlVFKQpvdmVyYWxsX2F2ZXJhZ2VfbW9tMV9wb3MgPC0gcm93TWVhbnMoYXZlcmFnZV9tb20xX3BvcywgbmEucm0gPSBUUlVFKQpvdmVyYWxsX2F2ZXJhZ2VfbW9tMl9wb3MgPC0gcm93TWVhbnMoYXZlcmFnZV9tb20yX3BvcywgbmEucm0gPSBUUlVFKQoKIyBQbG90IHRoZSBvdmVyYWxsIGF2ZXJhZ2VzCnBsb3Qob3ZlcmFsbF9hdmVyYWdlX01NX3BvcywgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJibGFjayIsIG1haW4gPSAiT3ZlcmFsbCBBdmVyYWdlIFBvc2l0aW9uIiwgeGxhYiA9ICJQb3NpdGlvbiBpbiBMaXN0IiwgeWxhYiA9ICJWYWx1ZSIsIHlsaW0gPSBjKG1pbihjKG92ZXJhbGxfYXZlcmFnZV9NTV9wb3MsIG92ZXJhbGxfYXZlcmFnZV9TdG9jaE5vaXN5MV9wb3MsIG92ZXJhbGxfYXZlcmFnZV9TdG9jaE5vaXN5Ml9wb3MsIG92ZXJhbGxfYXZlcmFnZV9tcjFfcG9zLCBvdmVyYWxsX2F2ZXJhZ2VfbXIyX3Bvcywgb3ZlcmFsbF9hdmVyYWdlX21vbTFfcG9zLCBvdmVyYWxsX2F2ZXJhZ2VfbW9tMl9wb3MpKSwgbWF4KGMob3ZlcmFsbF9hdmVyYWdlX01NX3Bvcywgb3ZlcmFsbF9hdmVyYWdlX1N0b2NoTm9pc3kxX3Bvcywgb3ZlcmFsbF9hdmVyYWdlX1N0b2NoTm9pc3kyX3Bvcywgb3ZlcmFsbF9hdmVyYWdlX21yMV9wb3MsIG92ZXJhbGxfYXZlcmFnZV9tcjJfcG9zLCBvdmVyYWxsX2F2ZXJhZ2VfbW9tMV9wb3MsIG92ZXJhbGxfYXZlcmFnZV9tb20yX3BvcykpKSkKbGluZXMob3ZlcmFsbF9hdmVyYWdlX1N0b2NoTm9pc3kxX3BvcywgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJyZWQiKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfU3RvY2hOb2lzeTJfcG9zLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gImdyZWVuIikKbGluZXMob3ZlcmFsbF9hdmVyYWdlX21yMV9wb3MsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAieWVsbG93IikKbGluZXMob3ZlcmFsbF9hdmVyYWdlX21yMl9wb3MsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAiYmx1ZSIpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9tb20xX3BvcywgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJwdXJwbGUiKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfbW9tMl9wb3MsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAib3JhbmdlIikKCiMgQWRkIGxlZ2VuZApsZWdlbmQoInRvcGxlZnQiLCBsZWdlbmQgPSBjKCJNYXJrZXQgTWFrZXIiLCAiU3RvY2hhc3RpYyBOb2lzeSAxIiwgIlN0b2NoYXN0aWMgTm9pc3kgMiIsICJNZWFuIFJldmVyc2lvbiAxIiwgIk1lYW4gUmV2ZXJzaW9uIDIiLCAiTW9tZW50dW0gMSIsICJNb21lbnR1bSAyIiksIGNvbCA9IGMoImJsYWNrIiwgInJlZCIsICJncmVlbiIsICJ5ZWxsb3ciLCAiYmx1ZSIsICJwdXJwbGUiLCAib3JhbmdlIiksIGx0eSA9IDEsIGNleCA9IDAuOCkKYGBgCgoKCiMjIHNldCA0ICgxIGluZm9ybWVkICsgMiBub2lzeSBpbmZvcm1lZCArIDIgbm9pc3kgKyAxIHN0b2NoYXN0aWMgbm9pc3kpCgpgYGB7cn0KIyBJbml0aWFsaXplIGVtcHR5IHZlY3RvcnMgdG8gc3RvcmUgdHJ1ZSBhbmQgZXhwZWN0ZWQgdmFsdWVzClRydWVWYWx1ZXNfc2V0NCA8LSBudW1lcmljKCkKRXhwZWN0ZWRWYWx1ZXNfc2V0NCA8LSBudW1lcmljKCkKCiMgTG9vcCB0aHJvdWdoIGVhY2ggaXRlcmF0aW9uIChuKQpmb3IgKG4gaW4gMToxMCkgewogICMgRXh0cmFjdCBUcnVlIHZhbHVlcyBmcm9tIHRoZSBhZ2dyZWdhdGVkX3Jlc3VsdHNfMSBkYXRhZnJhbWUKICBUcnVlVmFsdWVfc2V0NCA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfNFtuLCAyXSkpLCAiLCAiKVtbMV1dCiAgCiAgIyBFeHRyYWN0IEV4cGVjdGVkIHZhbHVlcyBmcm9tIHRoZSBhZ2dyZWdhdGVkX3Jlc3VsdHNfMSBkYXRhZnJhbWUKICBFeHBlY3RlZFZhbHVlX3NldDQgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzRbbiwgM10pKSwgIiwgIilbWzFdXQogIAogICMgQXBwZW5kIHRoZSBUcnVlIGFuZCBFeHBlY3RlZCB2YWx1ZXMgdG8gdGhlaXIgcmVzcGVjdGl2ZSB2ZWN0b3JzCiAgVHJ1ZVZhbHVlc19zZXQ0IDwtIGMoVHJ1ZVZhbHVlc19zZXQ0LCBhcy5udW1lcmljKFRydWVWYWx1ZV9zZXQ0KSkKICBFeHBlY3RlZFZhbHVlc19zZXQ0IDwtIGMoRXhwZWN0ZWRWYWx1ZXNfc2V0NCwgYXMubnVtZXJpYyhFeHBlY3RlZFZhbHVlX3NldDQpKQp9CgojIENhbGN1bGF0ZSB0aGUgYXZlcmFnZSBvZiBUcnVlIHZhbHVlcwphdmVyYWdlX3RydWUgPC0gbWVhbihUcnVlVmFsdWVzX3NldDQpCgojIENhbGN1bGF0ZSB0aGUgYXZlcmFnZSBvZiBFeHBlY3RlZCB2YWx1ZXMKYXZlcmFnZV9leHBlY3RlZCA8LSBtZWFuKEV4cGVjdGVkVmFsdWVzX3NldDQpCgojIFBsb3QgVHJ1ZSBhbmQgRXhwZWN0ZWQgdmFsdWVzIG9uIHRoZSBzYW1lIHBsb3QKcGxvdChUcnVlVmFsdWVzX3NldDQsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAiYmx1ZSIsIG1haW4gPSAiVHJ1ZSB2cyBFeHBlY3RlZCBWYWx1ZXMgaW4gc2V0IDQiLCB4bGFiID0gIkl0ZXJhdGlvbiIsIHlsYWIgPSAiVmFsdWUiKQpsaW5lcyhFeHBlY3RlZFZhbHVlc19zZXQ0LCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gInJlZCIpCgojIEFkZCBsZWdlbmQKbGVnZW5kKCJ0b3ByaWdodCIsIGxlZ2VuZCA9IGMoIlRydWUgVmFsdWVzIiwgIkV4cGVjdGVkIFZhbHVlcyIpLCBjb2wgPSBjKCJibHVlIiwgInJlZCIpLCBsdHkgPSAxLCBjZXggPSAwLjgpCgojIEFkZCBob3Jpem9udGFsIGxpbmVzIGZvciB0aGUgYXZlcmFnZXMKYWJsaW5lKGggPSBhdmVyYWdlX3RydWUsIGNvbCA9ICJibHVlIiwgbHdkID0gMSkKYWJsaW5lKGggPSBhdmVyYWdlX2V4cGVjdGVkLCBjb2wgPSAicmVkIiwgbHdkID0gMSkKYGBgCgpgYGB7cn0KIyBJbml0aWFsaXplIG1hdHJpY2VzIHRvIHN0b3JlIGF2ZXJhZ2VzIGZvciBlYWNoIHBvc2l0aW9uCmF2ZXJhZ2VfdHJ1ZSA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKYXZlcmFnZV9leHBlY3RlZCA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKCiMgTG9vcCB0aHJvdWdoIGVhY2ggc2ltdWxhdGlvbiAobikKZm9yIChuIGluIDE6MTApIHsKICAjIEV4dHJhY3QgVHJ1ZSB2YWx1ZXMgZnJvbSB0aGUgYWdncmVnYXRlZF9yZXN1bHRzXzQgZGF0YWZyYW1lCiAgVHJ1ZVZhbHVlc19zZXQ0IDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c180W24sIDJdKSksICIsICIpCiAgCiAgIyBFeHRyYWN0IEV4cGVjdGVkIHZhbHVlcyBmcm9tIHRoZSBhZ2dyZWdhdGVkX3Jlc3VsdHNfNCBkYXRhZnJhbWUKICBFeHBlY3RlZFZhbHVlc19zZXQ0IDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c180W24sIDNdKSksICIsICIpCiAgCiAgIyBMb29wIHRocm91Z2ggZWFjaCBwb3NpdGlvbiAoaSkKICBmb3IgKGkgaW4gMToxMDApIHsKICAgICMgRXh0cmFjdCBUcnVlIGFuZCBFeHBlY3RlZCB2YWx1ZXMgZm9yIHRoZSBpLXRoIHBvc2l0aW9uCiAgICBUcnVlX3ZhbHVlcyA8LSBzYXBwbHkoVHJ1ZVZhbHVlc19zZXQ0LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgRXhwZWN0ZWRfdmFsdWVzIDwtIHNhcHBseShFeHBlY3RlZFZhbHVlc19zZXQ0LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgCiAgICAjIENhbGN1bGF0ZSB0aGUgYXZlcmFnZSBvZiBUcnVlIGFuZCBFeHBlY3RlZCB2YWx1ZXMgZm9yIHRoZSBpLXRoIHBvc2l0aW9uCiAgICBhdmVyYWdlX3RydWVbaSwgbl0gPC0gbWVhbihUcnVlX3ZhbHVlcywgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9leHBlY3RlZFtpLCBuXSA8LSBtZWFuKEV4cGVjdGVkX3ZhbHVlcywgbmEucm0gPSBUUlVFKQogIH0KfQoKIyBDYWxjdWxhdGUgdGhlIG92ZXJhbGwgYXZlcmFnZSBmb3IgZWFjaCBwb3NpdGlvbiBhY3Jvc3MgYWxsIHNpbXVsYXRpb25zCm92ZXJhbGxfYXZlcmFnZV90cnVlIDwtIHJvd01lYW5zKGF2ZXJhZ2VfdHJ1ZSwgbmEucm0gPSBUUlVFKQpvdmVyYWxsX2F2ZXJhZ2VfZXhwZWN0ZWQgPC0gcm93TWVhbnMoYXZlcmFnZV9leHBlY3RlZCwgbmEucm0gPSBUUlVFKQoKIyBQbG90IHRoZSBvdmVyYWxsIGF2ZXJhZ2VzCnBsb3Qob3ZlcmFsbF9hdmVyYWdlX3RydWUsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAiYmx1ZSIsIG1haW4gPSAiT3ZlcmFsbCBBdmVyYWdlIG9mIFRydWUgdnMgRXhwZWN0ZWQgVmFsdWVzIiwgeGxhYiA9ICJQb3NpdGlvbiBpbiBMaXN0IiwgeWxhYiA9ICJWYWx1ZSIsIHlsaW0gPSBjKG1pbihjKG92ZXJhbGxfYXZlcmFnZV90cnVlLCBvdmVyYWxsX2F2ZXJhZ2VfZXhwZWN0ZWQpKSwgbWF4KGMob3ZlcmFsbF9hdmVyYWdlX3RydWUsIG92ZXJhbGxfYXZlcmFnZV9leHBlY3RlZCkpKSkKbGluZXMob3ZlcmFsbF9hdmVyYWdlX2V4cGVjdGVkLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gInJlZCIpCmxlZ2VuZCgidG9wcmlnaHQiLCBsZWdlbmQgPSBjKCJUcnVlIFZhbHVlcyIsICJFeHBlY3RlZCBWYWx1ZXMiKSwgY29sID0gYygiYmx1ZSIsICJyZWQiKSwgbHR5ID0gMSwgY2V4ID0gMC44KQoKYGBgCgoKCgpgYGB7cn0KIyBJbml0aWFsaXplIGVtcHR5IHZlY3RvcnMgdG8gc3RvcmUgdGhlIEJpZCBhbmQgQXNrIHZhbHVlcwpCaWRzX3NldDQgPC0gbnVtZXJpYygpCkFza3Nfc2V0NCA8LSBudW1lcmljKCkKCiMgTG9vcCB0aHJvdWdoIGVhY2ggaXRlcmF0aW9uIChuKQpmb3IgKG4gaW4gMToxMCkgewogICMgRXh0cmFjdCBCaWQgdmFsdWVzIGZyb20gdGhlIGFnZ3JlZ2F0ZWRfcmVzdWx0c18xIGRhdGFmcmFtZQogIEJpZF9zZXQ0IDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c180W24sIDRdKSksICIsICIpW1sxXV0KICAKICAjIEV4dHJhY3QgQXNrIHZhbHVlcyBmcm9tIHRoZSBhZ2dyZWdhdGVkX3Jlc3VsdHNfMSBkYXRhZnJhbWUgKG5leHQgY29sdW1uKQogIEFza19zZXQ0IDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c180W24sIDVdKSksICIsICIpW1sxXV0KICAKICAjIEFwcGVuZCB0aGUgQmlkIGFuZCBBc2sgdmFsdWVzIHRvIHRoZWlyIHJlc3BlY3RpdmUgdmVjdG9ycwogIEJpZHNfc2V0NCA8LSBjKEJpZHNfc2V0NCwgYXMubnVtZXJpYyhCaWRfc2V0NCkpCiAgQXNrc19zZXQ0IDwtIGMoQXNrc19zZXQ0LCBhcy5udW1lcmljKEFza19zZXQ0KSkKfQoKIyBDYWxjdWxhdGUgdGhlIGF2ZXJhZ2Ugb2YgQmlkIGFuZCBBc2sgdmFsdWVzCmF2ZXJhZ2VfYmlkcyA8LSBtZWFuKEJpZHNfc2V0NCwgbmEucm0gPSBUUlVFKQphdmVyYWdlX2Fza3MgPC0gbWVhbihBc2tzX3NldDQsIG5hLnJtID0gVFJVRSkKCiMgUGxvdCB0aGUgQmlkIGFuZCBBc2sgdmFsdWVzIG9uIHRoZSBzYW1lIHBsb3QKcGxvdChCaWRzX3NldDQsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAiYmx1ZSIsIG1haW4gPSAiQmlkcyB2cyBBc2tzIGluIHNldCA0IiwgeGxhYiA9ICJJdGVyYXRpb24iLCB5bGFiID0gIlZhbHVlIiwgeWxpbSA9IGMobWluKGMoQmlkc19zZXQ0LCBBc2tzX3NldDQpKSwgbWF4KGMoQmlkc19zZXQ0LCBBc2tzX3NldDQpKSkpCmxpbmVzKEFza3Nfc2V0NCwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJyZWQiKQoKIyBBZGQgbGVnZW5kCmxlZ2VuZCgidG9wcmlnaHQiLCBsZWdlbmQgPSBjKCJCaWRzIiwgIkFza3MiKSwgY29sID0gYygiYmx1ZSIsICJyZWQiKSwgbHR5ID0gMSwgY2V4ID0gMC44KQoKIyBBZGQgaG9yaXpvbnRhbCBsaW5lcyBmb3IgdGhlIGF2ZXJhZ2VzCmFibGluZShoID0gYXZlcmFnZV9iaWRzLCBjb2wgPSAiYmx1ZSIsIGx0eSA9IDEpCmFibGluZShoID0gYXZlcmFnZV9hc2tzLCBjb2wgPSAicmVkIiwgbHR5ID0gMSkKYGBgCgoKYGBge3J9CiMgSW5pdGlhbGl6ZSBtYXRyaWNlcyB0byBzdG9yZSBhdmVyYWdlcyBmb3IgZWFjaCBwb3NpdGlvbgphdmVyYWdlX2JpZCA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKYXZlcmFnZV9hc2sgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCgojIExvb3AgdGhyb3VnaCBlYWNoIHNpbXVsYXRpb24gKG4pCmZvciAobiBpbiAxOjEwKSB7CiAgIyBFeHRyYWN0IFRydWUgdmFsdWVzIGZyb20gdGhlIGFnZ3JlZ2F0ZWRfcmVzdWx0c180IGRhdGFmcmFtZQogIEJpZHNfc2V0NCA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfNFtuLCA0XSkpLCAiLCAiKQogIAogICMgRXh0cmFjdCBFeHBlY3RlZCB2YWx1ZXMgZnJvbSB0aGUgYWdncmVnYXRlZF9yZXN1bHRzXzQgZGF0YWZyYW1lCiAgQXNrc19zZXQ0IDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c180W24sIDVdKSksICIsICIpCiAgCiAgIyBMb29wIHRocm91Z2ggZWFjaCBwb3NpdGlvbiAoaSkKICBmb3IgKGkgaW4gMToxMDApIHsKICAgICMgRXh0cmFjdCBUcnVlIGFuZCBFeHBlY3RlZCB2YWx1ZXMgZm9yIHRoZSBpLXRoIHBvc2l0aW9uCiAgICBCaWRzIDwtIHNhcHBseShCaWRzX3NldDQsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICBBc2tzIDwtIHNhcHBseShBc2tzX3NldDQsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICAKICAgICMgQ2FsY3VsYXRlIHRoZSBhdmVyYWdlIG9mIFRydWUgYW5kIEV4cGVjdGVkIHZhbHVlcyBmb3IgdGhlIGktdGggcG9zaXRpb24KICAgIGF2ZXJhZ2VfYmlkW2ksIG5dIDwtIG1lYW4oQmlkcywgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9hc2tbaSwgbl0gPC0gbWVhbihBc2tzLCBuYS5ybSA9IFRSVUUpCiAgfQp9CgojIENhbGN1bGF0ZSB0aGUgb3ZlcmFsbCBhdmVyYWdlIGZvciBlYWNoIHBvc2l0aW9uIGFjcm9zcyBhbGwgc2ltdWxhdGlvbnMKb3ZlcmFsbF9hdmVyYWdlX2JpZCA8LSByb3dNZWFucyhhdmVyYWdlX2JpZCwgbmEucm0gPSBUUlVFKQpvdmVyYWxsX2F2ZXJhZ2VfYXNrIDwtIHJvd01lYW5zKGF2ZXJhZ2VfYXNrLCBuYS5ybSA9IFRSVUUpCgojIFBsb3QgdGhlIG92ZXJhbGwgYXZlcmFnZXMKcGxvdChvdmVyYWxsX2F2ZXJhZ2VfYmlkLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gImJsdWUiLCBtYWluID0gIk92ZXJhbGwgQXZlcmFnZSBvZiBCaWRzIHZzIEFza3MiLCB4bGFiID0gIlBvc2l0aW9uIGluIExpc3QiLCB5bGFiID0gIlZhbHVlIiwgeWxpbSA9IGMobWluKGMob3ZlcmFsbF9hdmVyYWdlX2JpZCwgb3ZlcmFsbF9hdmVyYWdlX2FzaykpLCBtYXgoYyhvdmVyYWxsX2F2ZXJhZ2VfYmlkLCBvdmVyYWxsX2F2ZXJhZ2VfYXNrKSkpKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfYXNrLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gInJlZCIpCmxlZ2VuZCgidG9wcmlnaHQiLCBsZWdlbmQgPSBjKCJCaWRzIiwgIkFza3MiKSwgY29sID0gYygiYmx1ZSIsICJyZWQiKSwgbHR5ID0gMSwgY2V4ID0gMC44KQpgYGAKCmBgYHtyfQojIEluaXRpYWxpemUgbWF0cmljZXMgdG8gc3RvcmUgYXZlcmFnZXMgZm9yIGVhY2ggcG9zaXRpb24KYXZlcmFnZV9iaWQgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfYXNrIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQoKIyBMb29wIHRocm91Z2ggZWFjaCBzaW11bGF0aW9uIChuKQpmb3IgKG4gaW4gMToxMCkgewogICMgRXh0cmFjdCBUcnVlIHZhbHVlcyBmcm9tIHRoZSBhZ2dyZWdhdGVkX3Jlc3VsdHNfNCBkYXRhZnJhbWUKICBCaWRzX3NldDQgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzRbbiwgNF0pKSwgIiwgIikKICAKICAjIEV4dHJhY3QgRXhwZWN0ZWQgdmFsdWVzIGZyb20gdGhlIGFnZ3JlZ2F0ZWRfcmVzdWx0c180IGRhdGFmcmFtZQogIEFza3Nfc2V0NCA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfNFtuLCA1XSkpLCAiLCAiKQogIAogICMgTG9vcCB0aHJvdWdoIGVhY2ggcG9zaXRpb24gKGkpCiAgZm9yIChpIGluIDE6MTAwKSB7CiAgICAjIEV4dHJhY3QgVHJ1ZSBhbmQgRXhwZWN0ZWQgdmFsdWVzIGZvciB0aGUgaS10aCBwb3NpdGlvbgogICAgQmlkcyA8LSBzYXBwbHkoQmlkc19zZXQ0LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgQXNrcyA8LSBzYXBwbHkoQXNrc19zZXQ0LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgCiAgICAjIENhbGN1bGF0ZSB0aGUgYXZlcmFnZSBvZiBUcnVlIGFuZCBFeHBlY3RlZCB2YWx1ZXMgZm9yIHRoZSBpLXRoIHBvc2l0aW9uCiAgICBhdmVyYWdlX2JpZFtpLCBuXSA8LSBtZWFuKEJpZHMsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfYXNrW2ksIG5dIDwtIG1lYW4oQXNrcywgbmEucm0gPSBUUlVFKQogIH0KfQoKIyBDYWxjdWxhdGUgdGhlIG92ZXJhbGwgYXZlcmFnZSBmb3IgZWFjaCBwb3NpdGlvbiBhY3Jvc3MgYWxsIHNpbXVsYXRpb25zCm92ZXJhbGxfYXZlcmFnZV9iaWQgPC0gcm93TWVhbnMoYXZlcmFnZV9iaWQsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX2FzayA8LSByb3dNZWFucyhhdmVyYWdlX2FzaywgbmEucm0gPSBUUlVFKQoKIyMgVHJ1ZSBWYWx1ZQojIEluaXRpYWxpemUgbWF0cmljZXMgdG8gc3RvcmUgYXZlcmFnZXMgZm9yIGVhY2ggcG9zaXRpb24KYXZlcmFnZV90cnVlIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX2V4cGVjdGVkIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQoKIyBMb29wIHRocm91Z2ggZWFjaCBzaW11bGF0aW9uIChuKQpmb3IgKG4gaW4gMToxMCkgewogICMgRXh0cmFjdCBUcnVlIHZhbHVlcyBmcm9tIHRoZSBhZ2dyZWdhdGVkX3Jlc3VsdHNfNCBkYXRhZnJhbWUKICBUcnVlVmFsdWVzX3NldDQgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzRbbiwgMl0pKSwgIiwgIikKICAKICAjIEV4dHJhY3QgRXhwZWN0ZWQgdmFsdWVzIGZyb20gdGhlIGFnZ3JlZ2F0ZWRfcmVzdWx0c180IGRhdGFmcmFtZQogIEV4cGVjdGVkVmFsdWVzX3NldDQgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzRbbiwgM10pKSwgIiwgIikKICAKICAjIExvb3AgdGhyb3VnaCBlYWNoIHBvc2l0aW9uIChpKQogIGZvciAoaSBpbiAxOjEwMCkgewogICAgIyBFeHRyYWN0IFRydWUgYW5kIEV4cGVjdGVkIHZhbHVlcyBmb3IgdGhlIGktdGggcG9zaXRpb24KICAgIFRydWVfdmFsdWVzIDwtIHNhcHBseShUcnVlVmFsdWVzX3NldDQsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICBFeHBlY3RlZF92YWx1ZXMgPC0gc2FwcGx5KEV4cGVjdGVkVmFsdWVzX3NldDQsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICAKICAgICMgQ2FsY3VsYXRlIHRoZSBhdmVyYWdlIG9mIFRydWUgYW5kIEV4cGVjdGVkIHZhbHVlcyBmb3IgdGhlIGktdGggcG9zaXRpb24KICAgIGF2ZXJhZ2VfdHJ1ZVtpLCBuXSA8LSBtZWFuKFRydWVfdmFsdWVzLCBuYS5ybSA9IFRSVUUpCiAgICBhdmVyYWdlX2V4cGVjdGVkW2ksIG5dIDwtIG1lYW4oRXhwZWN0ZWRfdmFsdWVzLCBuYS5ybSA9IFRSVUUpCiAgfQp9CgojIENhbGN1bGF0ZSB0aGUgb3ZlcmFsbCBhdmVyYWdlIGZvciBlYWNoIHBvc2l0aW9uIGFjcm9zcyBhbGwgc2ltdWxhdGlvbnMKb3ZlcmFsbF9hdmVyYWdlX3RydWUgPC0gcm93TWVhbnMoYXZlcmFnZV90cnVlLCBuYS5ybSA9IFRSVUUpCm92ZXJhbGxfYXZlcmFnZV9leHBlY3RlZCA8LSByb3dNZWFucyhhdmVyYWdlX2V4cGVjdGVkLCBuYS5ybSA9IFRSVUUpCgojIFBsb3QgdGhlIG92ZXJhbGwgYXZlcmFnZXMKI3Bsb3Qob3ZlcmFsbF9hdmVyYWdlX3RydWUsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAiYmx1ZSIsIG1haW4gPSAiT3ZlcmFsbCBBdmVyYWdlIG9mIFRydWUgdnMgRXhwZWN0ZWQgVmFsdWVzIiwgeGxhYiA9ICJQb3NpdGlvbiBpbiBMaXN0IiwgeWxhYiA9ICJWYWx1ZSIsIHlsaW0gPSBjKG1pbihjKG92ZXJhbGxfYXZlcmFnZV90cnVlLCBvdmVyYWxsX2F2ZXJhZ2VfZXhwZWN0ZWQpKSwgbWF4KGMob3ZlcmFsbF9hdmVyYWdlX3RydWUsIG92ZXJhbGxfYXZlcmFnZV9leHBlY3RlZCkpKSkKI2xpbmVzKG92ZXJhbGxfYXZlcmFnZV9leHBlY3RlZCwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJyZWQiKQojbGVnZW5kKCJ0b3ByaWdodCIsIGxlZ2VuZCA9IGMoIlRydWUgVmFsdWVzIiwgIkV4cGVjdGVkIFZhbHVlcyIpLCBjb2wgPSBjKCJibHVlIiwgInJlZCIpLCBsdHkgPSAxLCBjZXggPSAwLjgpCgojIFBsb3QgdGhlIG92ZXJhbGwgYXZlcmFnZXMKcGxvdChvdmVyYWxsX2F2ZXJhZ2VfYmlkLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gImJsdWUiLCBtYWluID0gIk92ZXJhbGwgQXZlcmFnZSBvZiBCaWRzIHZzIEFza3MgJiBUcnVlIHZzIEV4cGVjdGVkIFZhbHVlcyIsIHhsYWIgPSAiUG9zaXRpb24gaW4gTGlzdCIsIHlsYWIgPSAiVmFsdWUiLCB5bGltID0gYyhtaW4oYyhvdmVyYWxsX2F2ZXJhZ2VfYmlkLCBvdmVyYWxsX2F2ZXJhZ2VfYXNrLCBvdmVyYWxsX2F2ZXJhZ2VfdHJ1ZSwgb3ZlcmFsbF9hdmVyYWdlX2V4cGVjdGVkKSksIG1heChjKG92ZXJhbGxfYXZlcmFnZV9iaWQsIG92ZXJhbGxfYXZlcmFnZV9hc2ssIG92ZXJhbGxfYXZlcmFnZV90cnVlLCBvdmVyYWxsX2F2ZXJhZ2VfZXhwZWN0ZWQpKSkpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9hc2ssIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAicmVkIikKbGluZXMob3ZlcmFsbF9hdmVyYWdlX3RydWUsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAiZ3JlZW4iKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfZXhwZWN0ZWQsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAicHVycGxlIikKbGVnZW5kKCJib3R0b21sZWZ0IiwgbGVnZW5kID0gYygiQmlkcyIsICJBc2tzIiwgIlRydWUgVmFsdWUiLCAiRXhwZWN0ZWQgVmFsdWUiKSwgY29sID0gYygiYmx1ZSIsICJyZWQiLCAiZ3JlZW4iLCAicHVycGxlIiksIGx0eSA9IDEsIGNleCA9IDAuOCkKYGBgCgoKCmBgYHtyfQojIEluaXRpYWxpemUgZW1wdHkgdmVjdG9ycyB0byBzdG9yZSB0aGUgQmlkIGFuZCBBc2sgdmFsdWVzCk1NX3BubF9zZXQ0IDwtIG51bWVyaWMoKQpJbmZvcm1lZF9wbmxfc2V0NCA8LSBudW1lcmljKCkKTm9pc3lJbmZvcm1lZDFfcG5sX3NldDQgPC0gbnVtZXJpYygpCk5vaXN5SW5mb3JtZWQyX3BubF9zZXQ0IDwtIG51bWVyaWMoKQpOb2lzeTFfcG5sX3NldDQgPC0gbnVtZXJpYygpCk5vaXN5Ml9wbmxfc2V0NCA8LSBudW1lcmljKCkKU3RvY2hOb2lzeV9wbmxfc2V0NCA8LSBudW1lcmljKCkKCiMgTG9vcCB0aHJvdWdoIGVhY2ggaXRlcmF0aW9uIChuKQpmb3IgKG4gaW4gMToxMCkgewoKICBNTV9wbmxfdmFsdWVzIDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c180W24sIDZdKSksICIsICIpW1sxXV0KICAKICBJbmZvcm1lZF9wbmxfdmFsdWVzIDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c180W24sIDhdKSksICIsICIpW1sxXV0KICAKICBOb2lzeUluZm9ybWVkMV9wbmxfdmFsdWVzIDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c180W24sIDEwXSkpLCAiLCAiKVtbMV1dCiAgCiAgTm9pc3lJbmZvcm1lZDJfcG5sX3ZhbHVlcyA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfNFtuLCAxMl0pKSwgIiwgIilbWzFdXQogIAogIE5vaXN5MV9wbmxfdmFsdWVzIDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c180W24sIDE0XSkpLCAiLCAiKVtbMV1dCiAgCiAgTm9pc3kyX3BubF92YWx1ZXMgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzRbbiwgMTZdKSksICIsICIpW1sxXV0KICAKICBTdG9jaE5vaXN5X3BubF92YWx1ZXMgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzRbbiwgMThdKSksICIsICIpW1sxXV0KICAKICAjIENvbnZlcnQgQmlkIGFuZCBBc2sgdmFsdWVzIHRvIG51bWVyaWMgYW5kIGFwcGVuZCB0byB0aGUgdmVjdG9ycwogIE1NX3BubF9zZXQ0IDwtIGMoTU1fcG5sX3NldDQsIGFzLm51bWVyaWMoTU1fcG5sX3ZhbHVlcykpCiAgSW5mb3JtZWRfcG5sX3NldDQgPC0gYyhJbmZvcm1lZF9wbmxfc2V0NCwgYXMubnVtZXJpYyhJbmZvcm1lZF9wbmxfdmFsdWVzKSkKICBOb2lzeUluZm9ybWVkMV9wbmxfc2V0NCA8LSBjKE5vaXN5SW5mb3JtZWQxX3BubF9zZXQ0LCBhcy5udW1lcmljKE5vaXN5SW5mb3JtZWQxX3BubF92YWx1ZXMpKQogIE5vaXN5SW5mb3JtZWQyX3BubF9zZXQ0IDwtIGMoTm9pc3lJbmZvcm1lZDJfcG5sX3NldDQsIGFzLm51bWVyaWMoTm9pc3lJbmZvcm1lZDJfcG5sX3ZhbHVlcykpCiAgTm9pc3kxX3BubF9zZXQ0IDwtIGMoTm9pc3lfcG5sX3NldDQsIGFzLm51bWVyaWMoTm9pc3kxX3BubF92YWx1ZXMpKQogIE5vaXN5Ml9wbmxfc2V0NCA8LSBjKE5vaXN5Ml9wbmxfc2V0NCwgYXMubnVtZXJpYyhOb2lzeTJfcG5sX3ZhbHVlcykpCiAgU3RvY2hOb2lzeV9wbmxfc2V0NCA8LSBjKFN0b2NoTm9pc3lfcG5sX3NldDQsIGFzLm51bWVyaWMoU3RvY2hOb2lzeV9wbmxfdmFsdWVzKSkKfQoKIyBDYWxjdWxhdGUgdGhlIGF2ZXJhZ2Ugb2YgQmlkIGFuZCBBc2sgdmFsdWVzCiNhdmVyYWdlX01NIDwtIG1lYW4oTU1fc2V0NCwgbmEucm0gPSBUUlVFKQojYXZlcmFnZV9JTiA8LSBtZWFuKElOX3NldDQsIG5hLnJtID0gVFJVRSkKCiMgUGxvdCB0aGUgQmlkIGFuZCBBc2sgdmFsdWVzIG9uIHRoZSBzYW1lIHBsb3QKcGxvdChNTV9wbmxfc2V0NCwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJibGFjayIsIG1haW4gPSAiUE5MIGluIHNldCA0IiwgeGxhYiA9ICJJdGVyYXRpb24iLCB5bGFiID0gIlZhbHVlIiwgeWxpbSA9IGMobWluKGMoTU1fcG5sX3NldDQsIEluZm9ybWVkX3BubF9zZXQ0LCBOb2lzeUluZm9ybWVkMV9wbmxfc2V0NCwgTm9pc3lJbmZvcm1lZDJfcG5sX3NldDQsIE5vaXN5MV9wbmxfc2V0NCwgTm9pc3kyX3BubF9zZXQ0LCBTdG9jaE5vaXN5X3BubF9zZXQ0KSksIG1heChjKE1NX3BubF9zZXQ0LCBJbmZvcm1lZF9wbmxfc2V0NCwgTm9pc3lJbmZvcm1lZDFfcG5sX3NldDQsIE5vaXN5SW5mb3JtZWQyX3BubF9zZXQ0LCBOb2lzeTFfcG5sX3NldDQsIE5vaXN5Ml9wbmxfc2V0NCwgU3RvY2hOb2lzeV9wbmxfc2V0NCkpKSkKbGluZXMoSW5mb3JtZWRfcG5sX3NldDQsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAicmVkIikKbGluZXMoTm9pc3lJbmZvcm1lZDFfcG5sX3NldDQsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAiZ3JlZW4iKQpsaW5lcyhOb2lzeUluZm9ybWVkMl9wbmxfc2V0NCwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJ5ZWxsb3ciKQpsaW5lcyhOb2lzeTFfcG5sX3NldDQsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAiYmx1ZSIpCmxpbmVzKE5vaXN5Ml9wbmxfc2V0NCwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJwdXJwbGUiKQpsaW5lcyhTdG9jaE5vaXN5X3BubF9zZXQ0LCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gIm9yYW5nZSIpCgoKIyBBZGQgbGVnZW5kCmxlZ2VuZCgiYm90dG9tcmlnaHQiLCBsZWdlbmQgPSBjKCJNYXJrZXQgTWFrZXIiLCAiSW5mb3JtZWQiLCAiTm9pc3kgSW5mb3JtZWQgMSIsICJOb2lzeSBJbmZvcm1lZCAyIiwgIk5vaXN5IDEiLCAiTm9pc3kgMiIsICJTdG9jaGFzdGljIE5vaXN5IiksIGNvbCA9IGMoImJsYWNrIiwgInJlZCIsICJncmVlbiIsICJ5ZWxsb3ciLCAiYmx1ZSIsICJwdXJwbGUiLCAib3JhbmdlIiksIGx0eSA9IDEsIGNleCA9IDAuOCkKCiMgQWRkIGhvcml6b250YWwgbGluZXMgZm9yIHRoZSBhdmVyYWdlcwojYWJsaW5lKGggPSBhdmVyYWdlX01NLCBjb2wgPSAiYmx1ZSIsIGx0eSA9IDEpCiNhYmxpbmUoaCA9IGF2ZXJhZ2VfSU4sIGNvbCA9ICJyZWQiLCBsdHkgPSAxKQoKYGBgCgpgYGB7cn0KIyBJbml0aWFsaXplIG1hdHJpY2VzIHRvIHN0b3JlIGF2ZXJhZ2VzIGZvciBlYWNoIHBvc2l0aW9uCmF2ZXJhZ2VfTU1fcG5sIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX0luZm9ybWVkX3BubCA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKYXZlcmFnZV9Ob2lzeUluZm9ybWVkMV9wbmwgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfTm9pc3lJbmZvcm1lZDJfcG5sIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX05vaXN5MV9wbmwgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfTm9pc3kyX3BubCA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKYXZlcmFnZV9TdG9jaE5vaXN5X3BubCA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKCiMgTG9vcCB0aHJvdWdoIGVhY2ggc2ltdWxhdGlvbiAobikKZm9yIChuIGluIDE6MTApIHsKCiAgTU1fcG5sX3NldDQgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzRbbiwgNl0pKSwgIiwgIikKCiAgSW5mb3JtZWRfcG5sX3NldDQgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzRbbiwgOF0pKSwgIiwgIikKICAKICBOb2lzeUluZm9ybWVkMV9wbmxfc2V0NCA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfNFtuLCAxMF0pKSwgIiwgIikKICAKICBOb2lzeUluZm9ybWVkMl9wbmxfc2V0NCA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfNFtuLCAxMl0pKSwgIiwgIikKICAKICBOb2lzeTFfcG5sX3NldDQgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzRbbiwgMTRdKSksICIsICIpCiAgCiAgTm9pc3kyX3BubF9zZXQ0IDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c180W24sIDE2XSkpLCAiLCAiKQogIAogIFN0b2NoTm9pc3lfcG5sX3NldDQgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzRbbiwgMThdKSksICIsICIpCiAgCiAgIyBMb29wIHRocm91Z2ggZWFjaCBwb3NpdGlvbiAoaSkKICBmb3IgKGkgaW4gMToxMDApIHsKICAgICMgRXh0cmFjdCBUcnVlIGFuZCBFeHBlY3RlZCB2YWx1ZXMgZm9yIHRoZSBpLXRoIHBvc2l0aW9uCiAgICBNTV9wbmwgPC0gc2FwcGx5KE1NX3BubF9zZXQ0LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgSW5mb3JtZWRfcG5sIDwtIHNhcHBseShJbmZvcm1lZF9wbmxfc2V0NCwgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIE5vaXN5SW5mb3JtZWQxX3BubCA8LSBzYXBwbHkoTm9pc3lJbmZvcm1lZDFfcG5sX3NldDQsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICBOb2lzeUluZm9ybWVkMl9wbmwgPC0gc2FwcGx5KE5vaXN5SW5mb3JtZWQyX3BubF9zZXQ0LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgTm9pc3kxX3BubCA8LSBzYXBwbHkoTm9pc3kxX3BubF9zZXQ0LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgTm9pc3kyX3BubCA8LSBzYXBwbHkoTm9pc3kyX3BubF9zZXQ0LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgU3RvY2hOb2lzeV9wbmwgPC0gc2FwcGx5KFN0b2NoTm9pc3lfcG5sX3NldDQsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICAKICAgICMgQ2FsY3VsYXRlIHRoZSBhdmVyYWdlIG9mIFRydWUgYW5kIEV4cGVjdGVkIHZhbHVlcyBmb3IgdGhlIGktdGggcG9zaXRpb24KICAgIGF2ZXJhZ2VfTU1fcG5sW2ksIG5dIDwtIG1lYW4oTU1fcG5sLCBuYS5ybSA9IFRSVUUpCiAgICBhdmVyYWdlX0luZm9ybWVkX3BubFtpLCBuXSA8LSBtZWFuKEluZm9ybWVkX3BubCwgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9Ob2lzeUluZm9ybWVkMV9wbmxbaSwgbl0gPC0gbWVhbihOb2lzeUluZm9ybWVkMV9wbmwsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfTm9pc3lJbmZvcm1lZDJfcG5sW2ksIG5dIDwtIG1lYW4oTm9pc3lJbmZvcm1lZDJfcG5sLCBuYS5ybSA9IFRSVUUpCiAgICBhdmVyYWdlX05vaXN5MV9wbmxbaSwgbl0gPC0gbWVhbihOb2lzeTFfcG5sLCBuYS5ybSA9IFRSVUUpCiAgICBhdmVyYWdlX05vaXN5Ml9wbmxbaSwgbl0gPC0gbWVhbihOb2lzeTJfcG5sLCBuYS5ybSA9IFRSVUUpCiAgICBhdmVyYWdlX1N0b2NoTm9pc3lfcG5sW2ksIG5dIDwtIG1lYW4oU3RvY2hOb2lzeV9wbmwsIG5hLnJtID0gVFJVRSkKICB9Cn0KCiMgQ2FsY3VsYXRlIHRoZSBvdmVyYWxsIGF2ZXJhZ2UgZm9yIGVhY2ggcG9zaXRpb24gYWNyb3NzIGFsbCBzaW11bGF0aW9ucwpvdmVyYWxsX2F2ZXJhZ2VfTU1fcG5sIDwtIHJvd01lYW5zKGF2ZXJhZ2VfTU1fcG5sLCBuYS5ybSA9IFRSVUUpCm92ZXJhbGxfYXZlcmFnZV9JbmZvcm1lZF9wbmwgPC0gcm93TWVhbnMoYXZlcmFnZV9JbmZvcm1lZF9wbmwsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX05vaXN5SW5mb3JtZWQxX3BubCA8LSByb3dNZWFucyhhdmVyYWdlX05vaXN5SW5mb3JtZWQxX3BubCwgbmEucm0gPSBUUlVFKQpvdmVyYWxsX2F2ZXJhZ2VfTm9pc3lJbmZvcm1lZDJfcG5sIDwtIHJvd01lYW5zKGF2ZXJhZ2VfTm9pc3lJbmZvcm1lZDJfcG5sLCBuYS5ybSA9IFRSVUUpCm92ZXJhbGxfYXZlcmFnZV9Ob2lzeTFfcG5sIDwtIHJvd01lYW5zKGF2ZXJhZ2VfTm9pc3kxX3BubCwgbmEucm0gPSBUUlVFKQpvdmVyYWxsX2F2ZXJhZ2VfTm9pc3kyX3BubCA8LSByb3dNZWFucyhhdmVyYWdlX05vaXN5Ml9wbmwsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX1N0b2NoTm9pc3lfcG5sIDwtIHJvd01lYW5zKGF2ZXJhZ2VfU3RvY2hOb2lzeV9wbmwsIG5hLnJtID0gVFJVRSkKCiMgUGxvdCB0aGUgb3ZlcmFsbCBhdmVyYWdlcwpwbG90KG92ZXJhbGxfYXZlcmFnZV9NTV9wbmwsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAiYmxhY2siLCBtYWluID0gIk92ZXJhbGwgQXZlcmFnZSBQTkwiLCB4bGFiID0gIlBvc2l0aW9uIGluIExpc3QiLCB5bGFiID0gIlZhbHVlIiwgeWxpbSA9IGMobWluKGMob3ZlcmFsbF9hdmVyYWdlX01NX3BubCwgb3ZlcmFsbF9hdmVyYWdlX0luZm9ybWVkX3BubCwgb3ZlcmFsbF9hdmVyYWdlX05vaXN5SW5mb3JtZWQxX3BubCwgb3ZlcmFsbF9hdmVyYWdlX05vaXN5SW5mb3JtZWQyX3BubCwgb3ZlcmFsbF9hdmVyYWdlX05vaXN5MV9wbmwsIG92ZXJhbGxfYXZlcmFnZV9Ob2lzeTJfcG5sLCBvdmVyYWxsX2F2ZXJhZ2VfU3RvY2hOb2lzeV9wbmwpKSwgbWF4KGMob3ZlcmFsbF9hdmVyYWdlX01NX3BubCwgb3ZlcmFsbF9hdmVyYWdlX0luZm9ybWVkX3BubCwgb3ZlcmFsbF9hdmVyYWdlX05vaXN5SW5mb3JtZWQxX3BubCwgb3ZlcmFsbF9hdmVyYWdlX05vaXN5SW5mb3JtZWQyX3BubCwgb3ZlcmFsbF9hdmVyYWdlX05vaXN5MV9wbmwsIG92ZXJhbGxfYXZlcmFnZV9Ob2lzeTJfcG5sLCBvdmVyYWxsX2F2ZXJhZ2VfU3RvY2hOb2lzeV9wbmwpKSkpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9JbmZvcm1lZF9wbmwsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAicmVkIikKbGluZXMob3ZlcmFsbF9hdmVyYWdlX05vaXN5SW5mb3JtZWQxX3BubCwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJncmVlbiIpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9Ob2lzeUluZm9ybWVkMl9wbmwsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAieWVsbG93IikKbGluZXMob3ZlcmFsbF9hdmVyYWdlX05vaXN5MV9wbmwsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAiYmx1ZSIpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9Ob2lzeTJfcG5sLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gInB1cnBsZSIpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9TdG9jaE5vaXN5X3BubCwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJvcmFuZ2UiKQoKIyBBZGQgbGVnZW5kCmxlZ2VuZCgiYm90dG9tbGVmdCIsIGxlZ2VuZCA9IGMoIk1hcmtldCBNYWtlciIsICJJbmZvcm1lZCIsICJOb2lzeSBJbmZvcm1lZCAxIiwgIk5vaXN5IEluZm9ybWVkIDIiLCAiTm9pc3kgMSIsICJOb2lzeSAyIiwgIlN0b2NoYXN0aWMgTm9pc3kiKSwgY29sID0gYygiYmxhY2siLCAicmVkIiwgImdyZWVuIiwgInllbGxvdyIsICJibHVlIiwgInB1cnBsZSIsICJvcmFuZ2UiKSwgbHR5ID0gMSwgY2V4ID0gMC44KQpgYGAKCgpgYGB7cn0KIyBJbml0aWFsaXplIGVtcHR5IHZlY3RvcnMgdG8gc3RvcmUgdGhlIEJpZCBhbmQgQXNrIHZhbHVlcwpNTV9wb3Nfc2V0NCA8LSBudW1lcmljKCkKSW5mb3JtZWRfcG9zX3NldDQgPC0gbnVtZXJpYygpCk5vaXN5SW5mb3JtZWQxX3Bvc19zZXQ0IDwtIG51bWVyaWMoKQpOb2lzeUluZm9ybWVkMl9wb3Nfc2V0NCA8LSBudW1lcmljKCkKTm9pc3kxX3Bvc19zZXQ0IDwtIG51bWVyaWMoKQpOb2lzeTJfcG9zX3NldDQgPC0gbnVtZXJpYygpClN0b2NoTm9pc3lfcG9zX3NldDQgPC0gbnVtZXJpYygpCgojIExvb3AgdGhyb3VnaCBlYWNoIGl0ZXJhdGlvbiAobikKZm9yIChuIGluIDE6MTApIHsKCiAgTU1fcG9zX3ZhbHVlcyA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfNFtuLCA3XSkpLCAiLCAiKVtbMV1dCiAgCiAgSW5mb3JtZWRfcG9zX3ZhbHVlcyA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfNFtuLCA5XSkpLCAiLCAiKVtbMV1dCiAgCiAgTm9pc3lJbmZvcm1lZDFfcG9zX3ZhbHVlcyA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfNFtuLCAxMV0pKSwgIiwgIilbWzFdXQogIAogIE5vaXN5SW5mb3JtZWQyX3Bvc192YWx1ZXMgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzRbbiwgMTNdKSksICIsICIpW1sxXV0KICAKICBOb2lzeTFfcG9zX3ZhbHVlcyA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfNFtuLCAxNV0pKSwgIiwgIilbWzFdXQogIAogIE5vaXN5Ml9wb3NfdmFsdWVzIDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c180W24sIDE3XSkpLCAiLCAiKVtbMV1dCiAgCiAgU3RvY2hOb2lzeV9wb3NfdmFsdWVzIDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c180W24sIDE5XSkpLCAiLCAiKVtbMV1dCiAgCiAgIyBDb252ZXJ0IEJpZCBhbmQgQXNrIHZhbHVlcyB0byBudW1lcmljIGFuZCBhcHBlbmQgdG8gdGhlIHZlY3RvcnMKICBNTV9wb3Nfc2V0NCA8LSBjKE1NX3Bvc19zZXQ0LCBhcy5udW1lcmljKE1NX3Bvc192YWx1ZXMpKQogIEluZm9ybWVkX3Bvc19zZXQ0IDwtIGMoSW5mb3JtZWRfcG9zX3NldDQsIGFzLm51bWVyaWMoSW5mb3JtZWRfcG9zX3ZhbHVlcykpCiAgTm9pc3lJbmZvcm1lZDFfcG9zX3NldDQgPC0gYyhOb2lzeUluZm9ybWVkMV9wb3Nfc2V0NCwgYXMubnVtZXJpYyhOb2lzeUluZm9ybWVkMV9wb3NfdmFsdWVzKSkKICBOb2lzeUluZm9ybWVkMl9wb3Nfc2V0NCA8LSBjKE5vaXN5SW5mb3JtZWQyX3Bvc19zZXQ0LCBhcy5udW1lcmljKE5vaXN5SW5mb3JtZWQyX3Bvc192YWx1ZXMpKQogIE5vaXN5MV9wb3Nfc2V0NCA8LSBjKE5vaXN5X3Bvc19zZXQ0LCBhcy5udW1lcmljKE5vaXN5MV9wb3NfdmFsdWVzKSkKICBOb2lzeTJfcG9zX3NldDQgPC0gYyhOb2lzeTJfcG9zX3NldDQsIGFzLm51bWVyaWMoTm9pc3kyX3Bvc192YWx1ZXMpKQogIFN0b2NoTm9pc3lfcG9zX3NldDQgPC0gYyhTdG9jaE5vaXN5X3Bvc19zZXQ0LCBhcy5udW1lcmljKFN0b2NoTm9pc3lfcG9zX3ZhbHVlcykpCn0KCiMgQ2FsY3VsYXRlIHRoZSBhdmVyYWdlIG9mIEJpZCBhbmQgQXNrIHZhbHVlcwojYXZlcmFnZV9NTSA8LSBtZWFuKE1NX3NldDQsIG5hLnJtID0gVFJVRSkKI2F2ZXJhZ2VfSU4gPC0gbWVhbihJTl9zZXQ0LCBuYS5ybSA9IFRSVUUpCgojIFBsb3QgdGhlIEJpZCBhbmQgQXNrIHZhbHVlcyBvbiB0aGUgc2FtZSBwbG90CnBsb3QoTU1fcG9zX3NldDQsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAiYmxhY2siLCBtYWluID0gIlBvc2l0aW9uIGluIHNldCA0IiwgeGxhYiA9ICJJdGVyYXRpb24iLCB5bGFiID0gIlZhbHVlIiwgeWxpbSA9IGMobWluKGMoTU1fcG9zX3NldDQsIEluZm9ybWVkX3Bvc19zZXQ0LCBOb2lzeUluZm9ybWVkMV9wb3Nfc2V0NCwgTm9pc3lJbmZvcm1lZDJfcG9zX3NldDQsIE5vaXN5MV9wb3Nfc2V0NCwgTm9pc3kyX3Bvc19zZXQ0LCBTdG9jaE5vaXN5X3Bvc19zZXQ0KSksIG1heChjKE1NX3Bvc19zZXQ0LCBJbmZvcm1lZF9wb3Nfc2V0NCwgTm9pc3lJbmZvcm1lZDFfcG9zX3NldDQsIE5vaXN5SW5mb3JtZWQyX3Bvc19zZXQ0LCBOb2lzeTFfcG9zX3NldDQsIE5vaXN5Ml9wb3Nfc2V0NCwgU3RvY2hOb2lzeV9wb3Nfc2V0NCkpKSkKbGluZXMoSW5mb3JtZWRfcG9zX3NldDQsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAicmVkIikKbGluZXMoTm9pc3lJbmZvcm1lZDFfcG9zX3NldDQsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAiZ3JlZW4iKQpsaW5lcyhOb2lzeUluZm9ybWVkMl9wb3Nfc2V0NCwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJ5ZWxsb3ciKQpsaW5lcyhOb2lzeTFfcG9zX3NldDQsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAiYmx1ZSIpCmxpbmVzKE5vaXN5Ml9wb3Nfc2V0NCwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJwdXJwbGUiKQpsaW5lcyhTdG9jaE5vaXN5X3Bvc19zZXQ0LCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gIm9yYW5nZSIpCgoKIyBBZGQgbGVnZW5kCmxlZ2VuZCgidG9wbGVmdCIsIGxlZ2VuZCA9IGMoIk1hcmtldCBNYWtlciIsICJJbmZvcm1lZCIsICJOb2lzeSBJbmZvcm1lZCAxIiwgIk5vaXN5IEluZm9ybWVkIDIiLCAiTm9pc3kgMSIsICJOb2lzeSAyIiwgIlN0b2NoYXN0aWMgTm9pc3kiKSwgY29sID0gYygiYmxhY2siLCAicmVkIiwgImdyZWVuIiwgInllbGxvdyIsICJibHVlIiwgInB1cnBsZSIsICJvcmFuZ2UiKSwgbHR5ID0gMSwgY2V4ID0gMC44KQoKIyBBZGQgaG9yaXpvbnRhbCBsaW5lcyBmb3IgdGhlIGF2ZXJhZ2VzCiNhYmxpbmUoaCA9IGF2ZXJhZ2VfTU0sIGNvbCA9ICJibHVlIiwgbHR5ID0gMSkKI2FibGluZShoID0gYXZlcmFnZV9JTiwgY29sID0gInJlZCIsIGx0eSA9IDEpCmBgYAoKCmBgYHtyfQojIEluaXRpYWxpemUgbWF0cmljZXMgdG8gc3RvcmUgYXZlcmFnZXMgZm9yIGVhY2ggcG9zaXRpb24KYXZlcmFnZV9NTV9wb3MgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfSW5mb3JtZWRfcG9zIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX05vaXN5SW5mb3JtZWQxX3BvcyA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKYXZlcmFnZV9Ob2lzeUluZm9ybWVkMl9wb3MgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfTm9pc3kxX3BvcyA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKYXZlcmFnZV9Ob2lzeTJfcG9zIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX1N0b2NoTm9pc3lfcG9zIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQoKIyBMb29wIHRocm91Z2ggZWFjaCBzaW11bGF0aW9uIChuKQpmb3IgKG4gaW4gMToxMCkgewoKICBNTV9wb3Nfc2V0NCA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfNFtuLCA3XSkpLCAiLCAiKQoKICBJbmZvcm1lZF9wb3Nfc2V0NCA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfNFtuLCA5XSkpLCAiLCAiKQogIAogIE5vaXN5SW5mb3JtZWQxX3Bvc19zZXQ0IDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c180W24sIDExXSkpLCAiLCAiKQogIAogIE5vaXN5SW5mb3JtZWQyX3Bvc19zZXQ0IDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c180W24sIDEzXSkpLCAiLCAiKQogIAogIE5vaXN5MV9wb3Nfc2V0NCA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfNFtuLCAxNV0pKSwgIiwgIikKICAKICBOb2lzeTJfcG9zX3NldDQgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzRbbiwgMTddKSksICIsICIpCiAgCiAgU3RvY2hOb2lzeV9wb3Nfc2V0NCA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfNFtuLCAxOV0pKSwgIiwgIikKICAKICAjIExvb3AgdGhyb3VnaCBlYWNoIHBvc2l0aW9uIChpKQogIGZvciAoaSBpbiAxOjEwMCkgewogICAgIyBFeHRyYWN0IFRydWUgYW5kIEV4cGVjdGVkIHZhbHVlcyBmb3IgdGhlIGktdGggcG9zaXRpb24KICAgIE1NX3BvcyA8LSBzYXBwbHkoTU1fcG9zX3NldDQsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICBJbmZvcm1lZF9wb3MgPC0gc2FwcGx5KEluZm9ybWVkX3Bvc19zZXQ0LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgTm9pc3lJbmZvcm1lZDFfcG9zIDwtIHNhcHBseShOb2lzeUluZm9ybWVkMV9wb3Nfc2V0NCwgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIE5vaXN5SW5mb3JtZWQyX3BvcyA8LSBzYXBwbHkoTm9pc3lJbmZvcm1lZDJfcG9zX3NldDQsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICBOb2lzeTFfcG9zIDwtIHNhcHBseShOb2lzeTFfcG9zX3NldDQsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICBOb2lzeTJfcG9zIDwtIHNhcHBseShOb2lzeTJfcG9zX3NldDQsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICBTdG9jaE5vaXN5X3BvcyA8LSBzYXBwbHkoU3RvY2hOb2lzeV9wb3Nfc2V0NCwgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIAogICAgIyBDYWxjdWxhdGUgdGhlIGF2ZXJhZ2Ugb2YgVHJ1ZSBhbmQgRXhwZWN0ZWQgdmFsdWVzIGZvciB0aGUgaS10aCBwb3NpdGlvbgogICAgYXZlcmFnZV9NTV9wb3NbaSwgbl0gPC0gbWVhbihNTV9wb3MsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfSW5mb3JtZWRfcG9zW2ksIG5dIDwtIG1lYW4oSW5mb3JtZWRfcG9zLCBuYS5ybSA9IFRSVUUpCiAgICBhdmVyYWdlX05vaXN5SW5mb3JtZWQxX3Bvc1tpLCBuXSA8LSBtZWFuKE5vaXN5SW5mb3JtZWQxX3BvcywgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9Ob2lzeUluZm9ybWVkMl9wb3NbaSwgbl0gPC0gbWVhbihOb2lzeUluZm9ybWVkMl9wb3MsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfTm9pc3kxX3Bvc1tpLCBuXSA8LSBtZWFuKE5vaXN5MV9wb3MsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfTm9pc3kyX3Bvc1tpLCBuXSA8LSBtZWFuKE5vaXN5Ml9wb3MsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfU3RvY2hOb2lzeV9wb3NbaSwgbl0gPC0gbWVhbihTdG9jaE5vaXN5X3BvcywgbmEucm0gPSBUUlVFKQogIH0KfQoKIyBDYWxjdWxhdGUgdGhlIG92ZXJhbGwgYXZlcmFnZSBmb3IgZWFjaCBwb3NpdGlvbiBhY3Jvc3MgYWxsIHNpbXVsYXRpb25zCm92ZXJhbGxfYXZlcmFnZV9NTV9wb3MgPC0gcm93TWVhbnMoYXZlcmFnZV9NTV9wb3MsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX0luZm9ybWVkX3BvcyA8LSByb3dNZWFucyhhdmVyYWdlX0luZm9ybWVkX3BvcywgbmEucm0gPSBUUlVFKQpvdmVyYWxsX2F2ZXJhZ2VfTm9pc3lJbmZvcm1lZDFfcG9zIDwtIHJvd01lYW5zKGF2ZXJhZ2VfTm9pc3lJbmZvcm1lZDFfcG9zLCBuYS5ybSA9IFRSVUUpCm92ZXJhbGxfYXZlcmFnZV9Ob2lzeUluZm9ybWVkMl9wb3MgPC0gcm93TWVhbnMoYXZlcmFnZV9Ob2lzeUluZm9ybWVkMl9wb3MsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX05vaXN5MV9wb3MgPC0gcm93TWVhbnMoYXZlcmFnZV9Ob2lzeTFfcG9zLCBuYS5ybSA9IFRSVUUpCm92ZXJhbGxfYXZlcmFnZV9Ob2lzeTJfcG9zIDwtIHJvd01lYW5zKGF2ZXJhZ2VfTm9pc3kyX3BvcywgbmEucm0gPSBUUlVFKQpvdmVyYWxsX2F2ZXJhZ2VfU3RvY2hOb2lzeV9wb3MgPC0gcm93TWVhbnMoYXZlcmFnZV9TdG9jaE5vaXN5X3BvcywgbmEucm0gPSBUUlVFKQoKIyBQbG90IHRoZSBvdmVyYWxsIGF2ZXJhZ2VzCnBsb3Qob3ZlcmFsbF9hdmVyYWdlX01NX3BvcywgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJibGFjayIsIG1haW4gPSAiT3ZlcmFsbCBBdmVyYWdlIFBvc2l0aW9uIiwgeGxhYiA9ICJQb3NpdGlvbiBpbiBMaXN0IiwgeWxhYiA9ICJWYWx1ZSIsIHlsaW0gPSBjKG1pbihjKG92ZXJhbGxfYXZlcmFnZV9NTV9wb3MsIG92ZXJhbGxfYXZlcmFnZV9JbmZvcm1lZF9wb3MsIG92ZXJhbGxfYXZlcmFnZV9Ob2lzeUluZm9ybWVkMV9wb3MsIG92ZXJhbGxfYXZlcmFnZV9Ob2lzeUluZm9ybWVkMl9wb3MsIG92ZXJhbGxfYXZlcmFnZV9Ob2lzeTFfcG9zLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3kyX3Bvcywgb3ZlcmFsbF9hdmVyYWdlX1N0b2NoTm9pc3lfcG9zKSksIG1heChjKG92ZXJhbGxfYXZlcmFnZV9NTV9wb3MsIG92ZXJhbGxfYXZlcmFnZV9JbmZvcm1lZF9wb3MsIG92ZXJhbGxfYXZlcmFnZV9Ob2lzeUluZm9ybWVkMV9wb3MsIG92ZXJhbGxfYXZlcmFnZV9Ob2lzeUluZm9ybWVkMl9wb3MsIG92ZXJhbGxfYXZlcmFnZV9Ob2lzeTFfcG9zLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3kyX3Bvcywgb3ZlcmFsbF9hdmVyYWdlX1N0b2NoTm9pc3lfcG9zKSkpKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfSW5mb3JtZWRfcG9zLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gInJlZCIpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9Ob2lzeUluZm9ybWVkMV9wb3MsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAiZ3JlZW4iKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfTm9pc3lJbmZvcm1lZDJfcG9zLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gInllbGxvdyIpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9Ob2lzeTFfcG9zLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gImJsdWUiKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfTm9pc3kyX3BvcywgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJwdXJwbGUiKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfU3RvY2hOb2lzeV9wb3MsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAib3JhbmdlIikKCiMgQWRkIGxlZ2VuZApsZWdlbmQoImJvdHRvbWxlZnQiLCBsZWdlbmQgPSBjKCJNYXJrZXQgTWFrZXIiLCAiSW5mb3JtZWQiLCAiTm9pc3kgSW5mb3JtZWQgMSIsICJOb2lzeSBJbmZvcm1lZCAyIiwgIk5vaXN5IDEiLCAiTm9pc3kgMiIsICJTdG9jaGFzdGljIE5vaXN5IiksIGNvbCA9IGMoImJsYWNrIiwgInJlZCIsICJncmVlbiIsICJ5ZWxsb3ciLCAiYmx1ZSIsICJwdXJwbGUiLCAib3JhbmdlIiksIGx0eSA9IDEsIGNleCA9IDAuOCkKYGBgCgoKCiMjIHNldCA1IChOb2lzeSo2KQoKYGBge3J9CiMgSW5pdGlhbGl6ZSBtYXRyaWNlcyB0byBzdG9yZSBhdmVyYWdlcyBmb3IgZWFjaCBwb3NpdGlvbgphdmVyYWdlX3RydWUgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfZXhwZWN0ZWQgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCgojIExvb3AgdGhyb3VnaCBlYWNoIHNpbXVsYXRpb24gKG4pCmZvciAobiBpbiAxOjEwKSB7CiAgIyBFeHRyYWN0IFRydWUgdmFsdWVzIGZyb20gdGhlIGFnZ3JlZ2F0ZWRfcmVzdWx0c180IGRhdGFmcmFtZQogIFRydWVWYWx1ZXNfc2V0NSA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfNVtuLCAyXSkpLCAiLCAiKQogIAogICMgRXh0cmFjdCBFeHBlY3RlZCB2YWx1ZXMgZnJvbSB0aGUgYWdncmVnYXRlZF9yZXN1bHRzXzQgZGF0YWZyYW1lCiAgRXhwZWN0ZWRWYWx1ZXNfc2V0NSA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfNFtuLCAzXSkpLCAiLCAiKQogIAogICMgTG9vcCB0aHJvdWdoIGVhY2ggcG9zaXRpb24gKGkpCiAgZm9yIChpIGluIDE6MTAwKSB7CiAgICAjIEV4dHJhY3QgVHJ1ZSBhbmQgRXhwZWN0ZWQgdmFsdWVzIGZvciB0aGUgaS10aCBwb3NpdGlvbgogICAgVHJ1ZV92YWx1ZXMgPC0gc2FwcGx5KFRydWVWYWx1ZXNfc2V0NSwgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIEV4cGVjdGVkX3ZhbHVlcyA8LSBzYXBwbHkoRXhwZWN0ZWRWYWx1ZXNfc2V0NSwgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIAogICAgIyBDYWxjdWxhdGUgdGhlIGF2ZXJhZ2Ugb2YgVHJ1ZSBhbmQgRXhwZWN0ZWQgdmFsdWVzIGZvciB0aGUgaS10aCBwb3NpdGlvbgogICAgYXZlcmFnZV90cnVlW2ksIG5dIDwtIG1lYW4oVHJ1ZV92YWx1ZXMsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfZXhwZWN0ZWRbaSwgbl0gPC0gbWVhbihFeHBlY3RlZF92YWx1ZXMsIG5hLnJtID0gVFJVRSkKICB9Cn0KCiMgQ2FsY3VsYXRlIHRoZSBvdmVyYWxsIGF2ZXJhZ2UgZm9yIGVhY2ggcG9zaXRpb24gYWNyb3NzIGFsbCBzaW11bGF0aW9ucwpvdmVyYWxsX2F2ZXJhZ2VfdHJ1ZSA8LSByb3dNZWFucyhhdmVyYWdlX3RydWUsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX2V4cGVjdGVkIDwtIHJvd01lYW5zKGF2ZXJhZ2VfZXhwZWN0ZWQsIG5hLnJtID0gVFJVRSkKCiMgUGxvdCB0aGUgb3ZlcmFsbCBhdmVyYWdlcwpwbG90KG92ZXJhbGxfYXZlcmFnZV90cnVlLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gImJsdWUiLCBtYWluID0gIk92ZXJhbGwgQXZlcmFnZSBvZiBUcnVlIHZzIEV4cGVjdGVkIFZhbHVlcyIsIHhsYWIgPSAiUG9zaXRpb24gaW4gTGlzdCIsIHlsYWIgPSAiVmFsdWUiLCB5bGltID0gYyhtaW4oYyhvdmVyYWxsX2F2ZXJhZ2VfdHJ1ZSwgb3ZlcmFsbF9hdmVyYWdlX2V4cGVjdGVkKSksIG1heChjKG92ZXJhbGxfYXZlcmFnZV90cnVlLCBvdmVyYWxsX2F2ZXJhZ2VfZXhwZWN0ZWQpKSkpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9leHBlY3RlZCwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJyZWQiKQpsZWdlbmQoInRvcHJpZ2h0IiwgbGVnZW5kID0gYygiVHJ1ZSBWYWx1ZXMiLCAiRXhwZWN0ZWQgVmFsdWVzIiksIGNvbCA9IGMoImJsdWUiLCAicmVkIiksIGx0eSA9IDEsIGNleCA9IDAuOCkKYGBgCgoKYGBge3J9CiMgSW5pdGlhbGl6ZSBtYXRyaWNlcyB0byBzdG9yZSBhdmVyYWdlcyBmb3IgZWFjaCBwb3NpdGlvbgphdmVyYWdlX2JpZCA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKYXZlcmFnZV9hc2sgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCgojIExvb3AgdGhyb3VnaCBlYWNoIHNpbXVsYXRpb24gKG4pCmZvciAobiBpbiAxOjEwKSB7CiAgIyBFeHRyYWN0IFRydWUgdmFsdWVzIGZyb20gdGhlIGFnZ3JlZ2F0ZWRfcmVzdWx0c180IGRhdGFmcmFtZQogIEJpZHNfc2V0NSA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfNVtuLCA0XSkpLCAiLCAiKQogIAogICMgRXh0cmFjdCBFeHBlY3RlZCB2YWx1ZXMgZnJvbSB0aGUgYWdncmVnYXRlZF9yZXN1bHRzXzQgZGF0YWZyYW1lCiAgQXNrc19zZXQ1IDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c181W24sIDVdKSksICIsICIpCiAgCiAgIyBMb29wIHRocm91Z2ggZWFjaCBwb3NpdGlvbiAoaSkKICBmb3IgKGkgaW4gMToxMDApIHsKICAgICMgRXh0cmFjdCBUcnVlIGFuZCBFeHBlY3RlZCB2YWx1ZXMgZm9yIHRoZSBpLXRoIHBvc2l0aW9uCiAgICBCaWRzIDwtIHNhcHBseShCaWRzX3NldDUsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICBBc2tzIDwtIHNhcHBseShBc2tzX3NldDUsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICAKICAgICMgQ2FsY3VsYXRlIHRoZSBhdmVyYWdlIG9mIFRydWUgYW5kIEV4cGVjdGVkIHZhbHVlcyBmb3IgdGhlIGktdGggcG9zaXRpb24KICAgIGF2ZXJhZ2VfYmlkW2ksIG5dIDwtIG1lYW4oQmlkcywgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9hc2tbaSwgbl0gPC0gbWVhbihBc2tzLCBuYS5ybSA9IFRSVUUpCiAgfQp9CgojIENhbGN1bGF0ZSB0aGUgb3ZlcmFsbCBhdmVyYWdlIGZvciBlYWNoIHBvc2l0aW9uIGFjcm9zcyBhbGwgc2ltdWxhdGlvbnMKb3ZlcmFsbF9hdmVyYWdlX2JpZCA8LSByb3dNZWFucyhhdmVyYWdlX2JpZCwgbmEucm0gPSBUUlVFKQpvdmVyYWxsX2F2ZXJhZ2VfYXNrIDwtIHJvd01lYW5zKGF2ZXJhZ2VfYXNrLCBuYS5ybSA9IFRSVUUpCgojIFBsb3QgdGhlIG92ZXJhbGwgYXZlcmFnZXMKcGxvdChvdmVyYWxsX2F2ZXJhZ2VfYmlkLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gImJsdWUiLCBtYWluID0gIk92ZXJhbGwgQXZlcmFnZSBvZiBCaWRzIHZzIEFza3MiLCB4bGFiID0gIlBvc2l0aW9uIGluIExpc3QiLCB5bGFiID0gIlZhbHVlIiwgeWxpbSA9IGMobWluKGMob3ZlcmFsbF9hdmVyYWdlX2JpZCwgb3ZlcmFsbF9hdmVyYWdlX2FzaykpLCBtYXgoYyhvdmVyYWxsX2F2ZXJhZ2VfYmlkLCBvdmVyYWxsX2F2ZXJhZ2VfYXNrKSkpKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfYXNrLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gInJlZCIpCmxlZ2VuZCgidG9wcmlnaHQiLCBsZWdlbmQgPSBjKCJCaWRzIiwgIkFza3MiKSwgY29sID0gYygiYmx1ZSIsICJyZWQiKSwgbHR5ID0gMSwgY2V4ID0gMC44KQpgYGAKCmBgYHtyfQojIEluaXRpYWxpemUgbWF0cmljZXMgdG8gc3RvcmUgYXZlcmFnZXMgZm9yIGVhY2ggcG9zaXRpb24KYXZlcmFnZV9iaWQgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfYXNrIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQoKIyBMb29wIHRocm91Z2ggZWFjaCBzaW11bGF0aW9uIChuKQpmb3IgKG4gaW4gMToxMCkgewogICMgRXh0cmFjdCBUcnVlIHZhbHVlcyBmcm9tIHRoZSBhZ2dyZWdhdGVkX3Jlc3VsdHNfNCBkYXRhZnJhbWUKICBCaWRzX3NldDUgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzVbbiwgNF0pKSwgIiwgIikKICAKICAjIEV4dHJhY3QgRXhwZWN0ZWQgdmFsdWVzIGZyb20gdGhlIGFnZ3JlZ2F0ZWRfcmVzdWx0c180IGRhdGFmcmFtZQogIEFza3Nfc2V0NSA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfNVtuLCA1XSkpLCAiLCAiKQogIAogICMgTG9vcCB0aHJvdWdoIGVhY2ggcG9zaXRpb24gKGkpCiAgZm9yIChpIGluIDE6MTAwKSB7CiAgICAjIEV4dHJhY3QgVHJ1ZSBhbmQgRXhwZWN0ZWQgdmFsdWVzIGZvciB0aGUgaS10aCBwb3NpdGlvbgogICAgQmlkcyA8LSBzYXBwbHkoQmlkc19zZXQ1LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgQXNrcyA8LSBzYXBwbHkoQXNrc19zZXQ1LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgCiAgICAjIENhbGN1bGF0ZSB0aGUgYXZlcmFnZSBvZiBUcnVlIGFuZCBFeHBlY3RlZCB2YWx1ZXMgZm9yIHRoZSBpLXRoIHBvc2l0aW9uCiAgICBhdmVyYWdlX2JpZFtpLCBuXSA8LSBtZWFuKEJpZHMsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfYXNrW2ksIG5dIDwtIG1lYW4oQXNrcywgbmEucm0gPSBUUlVFKQogIH0KfQoKIyBDYWxjdWxhdGUgdGhlIG92ZXJhbGwgYXZlcmFnZSBmb3IgZWFjaCBwb3NpdGlvbiBhY3Jvc3MgYWxsIHNpbXVsYXRpb25zCm92ZXJhbGxfYXZlcmFnZV9iaWQgPC0gcm93TWVhbnMoYXZlcmFnZV9iaWQsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX2FzayA8LSByb3dNZWFucyhhdmVyYWdlX2FzaywgbmEucm0gPSBUUlVFKQoKIyMgVHJ1ZSBWYWx1ZQojIEluaXRpYWxpemUgbWF0cmljZXMgdG8gc3RvcmUgYXZlcmFnZXMgZm9yIGVhY2ggcG9zaXRpb24KYXZlcmFnZV90cnVlIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX2V4cGVjdGVkIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQoKIyBMb29wIHRocm91Z2ggZWFjaCBzaW11bGF0aW9uIChuKQpmb3IgKG4gaW4gMToxMCkgewogICMgRXh0cmFjdCBUcnVlIHZhbHVlcyBmcm9tIHRoZSBhZ2dyZWdhdGVkX3Jlc3VsdHNfNCBkYXRhZnJhbWUKICBUcnVlVmFsdWVzX3NldDUgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzVbbiwgMl0pKSwgIiwgIikKCiAgIyBFeHRyYWN0IEV4cGVjdGVkIHZhbHVlcyBmcm9tIHRoZSBhZ2dyZWdhdGVkX3Jlc3VsdHNfNCBkYXRhZnJhbWUKICBFeHBlY3RlZFZhbHVlc19zZXQ1IDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c181W24sIDNdKSksICIsICIpCiAgCiAgIyBMb29wIHRocm91Z2ggZWFjaCBwb3NpdGlvbiAoaSkKICBmb3IgKGkgaW4gMToxMDApIHsKICAgICMgRXh0cmFjdCBUcnVlIGFuZCBFeHBlY3RlZCB2YWx1ZXMgZm9yIHRoZSBpLXRoIHBvc2l0aW9uCiAgICBUcnVlX3ZhbHVlcyA8LSBzYXBwbHkoVHJ1ZVZhbHVlc19zZXQ1LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgRXhwZWN0ZWRfdmFsdWVzIDwtIHNhcHBseShFeHBlY3RlZFZhbHVlc19zZXQ1LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgCiAgICAjIENhbGN1bGF0ZSB0aGUgYXZlcmFnZSBvZiBUcnVlIGFuZCBFeHBlY3RlZCB2YWx1ZXMgZm9yIHRoZSBpLXRoIHBvc2l0aW9uCiAgICBhdmVyYWdlX3RydWVbaSwgbl0gPC0gbWVhbihUcnVlX3ZhbHVlcywgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9leHBlY3RlZFtpLCBuXSA8LSBtZWFuKEV4cGVjdGVkX3ZhbHVlcywgbmEucm0gPSBUUlVFKQogIH0KfQoKIyBDYWxjdWxhdGUgdGhlIG92ZXJhbGwgYXZlcmFnZSBmb3IgZWFjaCBwb3NpdGlvbiBhY3Jvc3MgYWxsIHNpbXVsYXRpb25zCm92ZXJhbGxfYXZlcmFnZV90cnVlIDwtIHJvd01lYW5zKGF2ZXJhZ2VfdHJ1ZSwgbmEucm0gPSBUUlVFKQpvdmVyYWxsX2F2ZXJhZ2VfZXhwZWN0ZWQgPC0gcm93TWVhbnMoYXZlcmFnZV9leHBlY3RlZCwgbmEucm0gPSBUUlVFKQoKIyBQbG90IHRoZSBvdmVyYWxsIGF2ZXJhZ2VzCiNwbG90KG92ZXJhbGxfYXZlcmFnZV90cnVlLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gImJsdWUiLCBtYWluID0gIk92ZXJhbGwgQXZlcmFnZSBvZiBUcnVlIHZzIEV4cGVjdGVkIFZhbHVlcyIsIHhsYWIgPSAiUG9zaXRpb24gaW4gTGlzdCIsIHlsYWIgPSAiVmFsdWUiLCB5bGltID0gYyhtaW4oYyhvdmVyYWxsX2F2ZXJhZ2VfdHJ1ZSwgb3ZlcmFsbF9hdmVyYWdlX2V4cGVjdGVkKSksIG1heChjKG92ZXJhbGxfYXZlcmFnZV90cnVlLCBvdmVyYWxsX2F2ZXJhZ2VfZXhwZWN0ZWQpKSkpCiNsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfZXhwZWN0ZWQsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAicmVkIikKI2xlZ2VuZCgidG9wcmlnaHQiLCBsZWdlbmQgPSBjKCJUcnVlIFZhbHVlcyIsICJFeHBlY3RlZCBWYWx1ZXMiKSwgY29sID0gYygiYmx1ZSIsICJyZWQiKSwgbHR5ID0gMSwgY2V4ID0gMC44KQoKIyBQbG90IHRoZSBvdmVyYWxsIGF2ZXJhZ2VzCnBsb3Qob3ZlcmFsbF9hdmVyYWdlX2JpZCwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJibHVlIiwgbWFpbiA9ICJPdmVyYWxsIEF2ZXJhZ2Ugb2YgQmlkcyB2cyBBc2tzICYgVHJ1ZSB2cyBFeHBlY3RlZCBWYWx1ZXMiLCB4bGFiID0gIlBvc2l0aW9uIGluIExpc3QiLCB5bGFiID0gIlZhbHVlIiwgeWxpbSA9IGMobWluKGMob3ZlcmFsbF9hdmVyYWdlX2JpZCwgb3ZlcmFsbF9hdmVyYWdlX2Fzaywgb3ZlcmFsbF9hdmVyYWdlX3RydWUsIG92ZXJhbGxfYXZlcmFnZV9leHBlY3RlZCkpLCBtYXgoYyhvdmVyYWxsX2F2ZXJhZ2VfYmlkLCBvdmVyYWxsX2F2ZXJhZ2VfYXNrLCBvdmVyYWxsX2F2ZXJhZ2VfdHJ1ZSwgb3ZlcmFsbF9hdmVyYWdlX2V4cGVjdGVkKSkpKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfYXNrLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gInJlZCIpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV90cnVlLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gImdyZWVuIikKbGluZXMob3ZlcmFsbF9hdmVyYWdlX2V4cGVjdGVkLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gInB1cnBsZSIpCmxlZ2VuZCgiYm90dG9tbGVmdCIsIGxlZ2VuZCA9IGMoIkJpZHMiLCAiQXNrcyIsICJUcnVlIFZhbHVlIiwgIkV4cGVjdGVkIFZhbHVlIiksIGNvbCA9IGMoImJsdWUiLCAicmVkIiwgImdyZWVuIiwgInB1cnBsZSIpLCBsdHkgPSAxLCBjZXggPSAwLjgpCmBgYAoKCmBgYHtyfQojIEluaXRpYWxpemUgbWF0cmljZXMgdG8gc3RvcmUgYXZlcmFnZXMgZm9yIGVhY2ggcG9zaXRpb24KYXZlcmFnZV9NTV9wbmwgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfTm9pc3kxX3BubCA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKYXZlcmFnZV9Ob2lzeTJfcG5sIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX05vaXN5M19wbmwgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfTm9pc3k0X3BubCA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKYXZlcmFnZV9Ob2lzeTVfcG5sIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX05vaXN5Nl9wbmwgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCgojIExvb3AgdGhyb3VnaCBlYWNoIHNpbXVsYXRpb24gKG4pCmZvciAobiBpbiAxOjEwKSB7CgogIE1NX3BubF9zZXQ1IDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c181W24sIDZdKSksICIsICIpCgogIE5vaXN5MV9wbmxfc2V0NSA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfNVtuLCA4XSkpLCAiLCAiKQogIAogIE5vaXN5Ml9wbmxfc2V0NSA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfNVtuLCAxMF0pKSwgIiwgIikKICAKICBOb2lzeTNfcG5sX3NldDUgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzVbbiwgMTJdKSksICIsICIpCiAgCiAgTm9pc3k0X3BubF9zZXQ1IDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c181W24sIDE0XSkpLCAiLCAiKQogIAogIE5vaXN5NV9wbmxfc2V0NSA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfNVtuLCAxNl0pKSwgIiwgIikKICAKICBOb2lzeTZfcG5sX3NldDUgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzVbbiwgMThdKSksICIsICIpCiAgCiAgIyBMb29wIHRocm91Z2ggZWFjaCBwb3NpdGlvbiAoaSkKICBmb3IgKGkgaW4gMToxMDApIHsKICAgICMgRXh0cmFjdCBUcnVlIGFuZCBFeHBlY3RlZCB2YWx1ZXMgZm9yIHRoZSBpLXRoIHBvc2l0aW9uCiAgICBNTV9wbmwgPC0gc2FwcGx5KE1NX3BubF9zZXQ1LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgTm9pc3kxX3BubCA8LSBzYXBwbHkoTm9pc3kxX3BubF9zZXQ1LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgTm9pc3kyX3BubCA8LSBzYXBwbHkoTm9pc3kyX3BubF9zZXQ1LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgTm9pc3kzX3BubCA8LSBzYXBwbHkoTm9pc3kzX3BubF9zZXQ1LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgTm9pc3k0X3BubCA8LSBzYXBwbHkoTm9pc3k0X3BubF9zZXQ1LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgTm9pc3k1X3BubCA8LSBzYXBwbHkoTm9pc3k1X3BubF9zZXQ1LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgTm9pc3k2X3BubCA8LSBzYXBwbHkoTm9pc3k2X3BubF9zZXQ1LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgCiAgICAjIENhbGN1bGF0ZSB0aGUgYXZlcmFnZSBvZiBUcnVlIGFuZCBFeHBlY3RlZCB2YWx1ZXMgZm9yIHRoZSBpLXRoIHBvc2l0aW9uCiAgICBhdmVyYWdlX01NX3BubFtpLCBuXSA8LSBtZWFuKE1NX3BubCwgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9Ob2lzeTFfcG5sW2ksIG5dIDwtIG1lYW4oTm9pc3kxX3BubCwgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9Ob2lzeTJfcG5sW2ksIG5dIDwtIG1lYW4oTm9pc3kyX3BubCwgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9Ob2lzeTNfcG5sW2ksIG5dIDwtIG1lYW4oTm9pc3kzX3BubCwgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9Ob2lzeTRfcG5sW2ksIG5dIDwtIG1lYW4oTm9pc3k0X3BubCwgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9Ob2lzeTVfcG5sW2ksIG5dIDwtIG1lYW4oTm9pc3k1X3BubCwgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9Ob2lzeTZfcG5sW2ksIG5dIDwtIG1lYW4oTm9pc3k2X3BubCwgbmEucm0gPSBUUlVFKQogIH0KfQoKIyBDYWxjdWxhdGUgdGhlIG92ZXJhbGwgYXZlcmFnZSBmb3IgZWFjaCBwb3NpdGlvbiBhY3Jvc3MgYWxsIHNpbXVsYXRpb25zCm92ZXJhbGxfYXZlcmFnZV9NTV9wbmwgPC0gcm93TWVhbnMoYXZlcmFnZV9NTV9wbmwsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX05vaXN5MV9wbmwgPC0gcm93TWVhbnMoYXZlcmFnZV9Ob2lzeTFfcG5sLCBuYS5ybSA9IFRSVUUpCm92ZXJhbGxfYXZlcmFnZV9Ob2lzeTJfcG5sIDwtIHJvd01lYW5zKGF2ZXJhZ2VfTm9pc3kyX3BubCwgbmEucm0gPSBUUlVFKQpvdmVyYWxsX2F2ZXJhZ2VfTm9pc3kzX3BubCA8LSByb3dNZWFucyhhdmVyYWdlX05vaXN5M19wbmwsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX05vaXN5NF9wbmwgPC0gcm93TWVhbnMoYXZlcmFnZV9Ob2lzeTRfcG5sLCBuYS5ybSA9IFRSVUUpCm92ZXJhbGxfYXZlcmFnZV9Ob2lzeTVfcG5sIDwtIHJvd01lYW5zKGF2ZXJhZ2VfTm9pc3k1X3BubCwgbmEucm0gPSBUUlVFKQpvdmVyYWxsX2F2ZXJhZ2VfTm9pc3k2X3BubCA8LSByb3dNZWFucyhhdmVyYWdlX05vaXN5Nl9wbmwsIG5hLnJtID0gVFJVRSkKCiMgUGxvdCB0aGUgb3ZlcmFsbCBhdmVyYWdlcwpwbG90KG92ZXJhbGxfYXZlcmFnZV9NTV9wbmwsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAiYmxhY2siLCBtYWluID0gIk92ZXJhbGwgQXZlcmFnZSBQTkwiLCB4bGFiID0gIlBvc2l0aW9uIGluIExpc3QiLCB5bGFiID0gIlZhbHVlIiwgeWxpbSA9IGMobWluKGMob3ZlcmFsbF9hdmVyYWdlX01NX3BubCwgb3ZlcmFsbF9hdmVyYWdlX05vaXN5MV9wbmwsIG92ZXJhbGxfYXZlcmFnZV9Ob2lzeTJfcG5sLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3kzX3BubCwgb3ZlcmFsbF9hdmVyYWdlX05vaXN5NF9wbmwsIG92ZXJhbGxfYXZlcmFnZV9Ob2lzeTVfcG5sLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3k2X3BubCkpLCBtYXgoYyhvdmVyYWxsX2F2ZXJhZ2VfTU1fcG5sLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3kxX3BubCwgb3ZlcmFsbF9hdmVyYWdlX05vaXN5Ml9wbmwsIG92ZXJhbGxfYXZlcmFnZV9Ob2lzeTNfcG5sLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3k0X3BubCwgb3ZlcmFsbF9hdmVyYWdlX05vaXN5NV9wbmwsIG92ZXJhbGxfYXZlcmFnZV9Ob2lzeTZfcG5sKSkpKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfTm9pc3kxX3BubCwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJyZWQiKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfTm9pc3kyX3BubCwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJncmVlbiIpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9Ob2lzeTNfcG5sLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gInllbGxvdyIpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9Ob2lzeTRfcG5sLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gImJsdWUiKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfTm9pc3k1X3BubCwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJwdXJwbGUiKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfTm9pc3k2X3BubCwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJvcmFuZ2UiKQoKIyBBZGQgbGVnZW5kCmxlZ2VuZCgiYm90dG9tbGVmdCIsIGxlZ2VuZCA9IGMoIk1hcmtldCBNYWtlciIsICJOb2lzeSAxIiwgIk5vaXN5IDIiLCAiTm9pc3kgMyIsICJOb2lzeSA0IiwgIk5vaXN5IDUiLCAiTm9pc3kgNiIpLCBjb2wgPSBjKCJibGFjayIsICJyZWQiLCAiZ3JlZW4iLCAieWVsbG93IiwgImJsdWUiLCAicHVycGxlIiwgIm9yYW5nZSIpLCBsdHkgPSAxLCBjZXggPSAwLjgpCmBgYAoKCmBgYHtyfQojIEluaXRpYWxpemUgbWF0cmljZXMgdG8gc3RvcmUgYXZlcmFnZXMgZm9yIGVhY2ggcG9zaXRpb24KYXZlcmFnZV9NTV9wb3MgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfTm9pc3kxX3BvcyA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKYXZlcmFnZV9Ob2lzeTJfcG9zIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX05vaXN5M19wb3MgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfTm9pc3k0X3BvcyA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKYXZlcmFnZV9Ob2lzeTVfcG9zIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX05vaXN5Nl9wb3MgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCgojIExvb3AgdGhyb3VnaCBlYWNoIHNpbXVsYXRpb24gKG4pCmZvciAobiBpbiAxOjEwKSB7CgogIE1NX3Bvc19zZXQ1IDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c181W24sIDddKSksICIsICIpCgogIE5vaXN5MV9wb3Nfc2V0NSA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfNVtuLCA5XSkpLCAiLCAiKQogIAogIE5vaXN5Ml9wb3Nfc2V0NSA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfNVtuLCAxMV0pKSwgIiwgIikKICAKICBOb2lzeTNfcG9zX3NldDUgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzVbbiwgMTNdKSksICIsICIpCiAgCiAgTm9pc3k0X3Bvc19zZXQ1IDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c181W24sIDE1XSkpLCAiLCAiKQogIAogIE5vaXN5NV9wb3Nfc2V0NSA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfNVtuLCAxN10pKSwgIiwgIikKICAKICBOb2lzeTZfcG9zX3NldDUgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzVbbiwgMTldKSksICIsICIpCiAgCiAgIyBMb29wIHRocm91Z2ggZWFjaCBwb3NpdGlvbiAoaSkKICBmb3IgKGkgaW4gMToxMDApIHsKICAgICMgRXh0cmFjdCBUcnVlIGFuZCBFeHBlY3RlZCB2YWx1ZXMgZm9yIHRoZSBpLXRoIHBvc2l0aW9uCiAgICBNTV9wb3MgPC0gc2FwcGx5KE1NX3Bvc19zZXQ1LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgTm9pc3kxX3BvcyA8LSBzYXBwbHkoTm9pc3kxX3Bvc19zZXQ1LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgTm9pc3kyX3BvcyA8LSBzYXBwbHkoTm9pc3kyX3Bvc19zZXQ1LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgTm9pc3kzX3BvcyA8LSBzYXBwbHkoTm9pc3kzX3Bvc19zZXQ1LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgTm9pc3k0X3BvcyA8LSBzYXBwbHkoTm9pc3k0X3Bvc19zZXQ1LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgTm9pc3k1X3BvcyA8LSBzYXBwbHkoTm9pc3k1X3Bvc19zZXQ1LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgTm9pc3k2X3BvcyA8LSBzYXBwbHkoTm9pc3k2X3Bvc19zZXQ1LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgCiAgICAjIENhbGN1bGF0ZSB0aGUgYXZlcmFnZSBvZiBUcnVlIGFuZCBFeHBlY3RlZCB2YWx1ZXMgZm9yIHRoZSBpLXRoIHBvc2l0aW9uCiAgICBhdmVyYWdlX01NX3Bvc1tpLCBuXSA8LSBtZWFuKE1NX3BvcywgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9Ob2lzeTFfcG9zW2ksIG5dIDwtIG1lYW4oTm9pc3kxX3BvcywgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9Ob2lzeTJfcG9zW2ksIG5dIDwtIG1lYW4oTm9pc3kyX3BvcywgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9Ob2lzeTNfcG9zW2ksIG5dIDwtIG1lYW4oTm9pc3kzX3BvcywgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9Ob2lzeTRfcG9zW2ksIG5dIDwtIG1lYW4oTm9pc3k0X3BvcywgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9Ob2lzeTVfcG9zW2ksIG5dIDwtIG1lYW4oTm9pc3k1X3BvcywgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9Ob2lzeTZfcG9zW2ksIG5dIDwtIG1lYW4oTm9pc3k2X3BvcywgbmEucm0gPSBUUlVFKQogIH0KfQoKIyBDYWxjdWxhdGUgdGhlIG92ZXJhbGwgYXZlcmFnZSBmb3IgZWFjaCBwb3NpdGlvbiBhY3Jvc3MgYWxsIHNpbXVsYXRpb25zCm92ZXJhbGxfYXZlcmFnZV9NTV9wb3MgPC0gcm93TWVhbnMoYXZlcmFnZV9NTV9wb3MsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX05vaXN5MV9wb3MgPC0gcm93TWVhbnMoYXZlcmFnZV9Ob2lzeTFfcG9zLCBuYS5ybSA9IFRSVUUpCm92ZXJhbGxfYXZlcmFnZV9Ob2lzeTJfcG9zIDwtIHJvd01lYW5zKGF2ZXJhZ2VfTm9pc3kyX3BvcywgbmEucm0gPSBUUlVFKQpvdmVyYWxsX2F2ZXJhZ2VfTm9pc3kzX3BvcyA8LSByb3dNZWFucyhhdmVyYWdlX05vaXN5M19wb3MsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX05vaXN5NF9wb3MgPC0gcm93TWVhbnMoYXZlcmFnZV9Ob2lzeTRfcG9zLCBuYS5ybSA9IFRSVUUpCm92ZXJhbGxfYXZlcmFnZV9Ob2lzeTVfcG9zIDwtIHJvd01lYW5zKGF2ZXJhZ2VfTm9pc3k1X3BvcywgbmEucm0gPSBUUlVFKQpvdmVyYWxsX2F2ZXJhZ2VfTm9pc3k2X3BvcyA8LSByb3dNZWFucyhhdmVyYWdlX05vaXN5Nl9wb3MsIG5hLnJtID0gVFJVRSkKCiMgUGxvdCB0aGUgb3ZlcmFsbCBhdmVyYWdlcwpwbG90KG92ZXJhbGxfYXZlcmFnZV9NTV9wb3MsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAiYmxhY2siLCBtYWluID0gIk92ZXJhbGwgQXZlcmFnZSBQb3NpdGlvbiIsIHhsYWIgPSAiUG9zaXRpb24gaW4gTGlzdCIsIHlsYWIgPSAiVmFsdWUiLCB5bGltID0gYyhtaW4oYyhvdmVyYWxsX2F2ZXJhZ2VfTU1fcG9zLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3kxX3Bvcywgb3ZlcmFsbF9hdmVyYWdlX05vaXN5Ml9wb3MsIG92ZXJhbGxfYXZlcmFnZV9Ob2lzeTNfcG9zLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3k0X3Bvcywgb3ZlcmFsbF9hdmVyYWdlX05vaXN5NV9wb3MsIG92ZXJhbGxfYXZlcmFnZV9Ob2lzeTZfcG9zKSksIG1heChjKG92ZXJhbGxfYXZlcmFnZV9NTV9wb3MsIG92ZXJhbGxfYXZlcmFnZV9Ob2lzeTFfcG9zLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3kyX3Bvcywgb3ZlcmFsbF9hdmVyYWdlX05vaXN5M19wb3MsIG92ZXJhbGxfYXZlcmFnZV9Ob2lzeTRfcG9zLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3k1X3Bvcywgb3ZlcmFsbF9hdmVyYWdlX05vaXN5Nl9wb3MpKSkpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9Ob2lzeTFfcG9zLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gInJlZCIpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9Ob2lzeTJfcG9zLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gImdyZWVuIikKbGluZXMob3ZlcmFsbF9hdmVyYWdlX05vaXN5M19wb3MsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAieWVsbG93IikKbGluZXMob3ZlcmFsbF9hdmVyYWdlX05vaXN5NF9wb3MsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAiYmx1ZSIpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9Ob2lzeTVfcG9zLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gInB1cnBsZSIpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9Ob2lzeTZfcG9zLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gIm9yYW5nZSIpCgojIEFkZCBsZWdlbmQKbGVnZW5kKCJib3R0b21yaWdodCIsIGxlZ2VuZCA9IGMoIk1hcmtldCBNYWtlciIsICJOb2lzeSAxIiwgIk5vaXN5IDIiLCAiTm9pc3kgMyIsICJOb2lzeSA0IiwgIk5vaXN5IDUiLCAiTm9pc3kgNiIpLCBjb2wgPSBjKCJibGFjayIsICJyZWQiLCAiZ3JlZW4iLCAieWVsbG93IiwgImJsdWUiLCAicHVycGxlIiwgIm9yYW5nZSIpLCBsdHkgPSAxLCBjZXggPSAwLjgpCmBgYAoKCiMjIHNldDYgKDEgaW5mb3JtZWQgKyA1IG5vaXN5KQoKYGBge3J9CiMgSW5pdGlhbGl6ZSBtYXRyaWNlcyB0byBzdG9yZSBhdmVyYWdlcyBmb3IgZWFjaCBwb3NpdGlvbgphdmVyYWdlX3RydWUgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfZXhwZWN0ZWQgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCgojIExvb3AgdGhyb3VnaCBlYWNoIHNpbXVsYXRpb24gKG4pCmZvciAobiBpbiAxOjEwKSB7CiAgIyBFeHRyYWN0IFRydWUgdmFsdWVzIGZyb20gdGhlIGFnZ3JlZ2F0ZWRfcmVzdWx0c180IGRhdGFmcmFtZQogIFRydWVWYWx1ZXNfc2V0NiA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfNltuLCAyXSkpLCAiLCAiKQogIAogICMgRXh0cmFjdCBFeHBlY3RlZCB2YWx1ZXMgZnJvbSB0aGUgYWdncmVnYXRlZF9yZXN1bHRzXzQgZGF0YWZyYW1lCiAgRXhwZWN0ZWRWYWx1ZXNfc2V0NiA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfNltuLCAzXSkpLCAiLCAiKQogIAogICMgTG9vcCB0aHJvdWdoIGVhY2ggcG9zaXRpb24gKGkpCiAgZm9yIChpIGluIDE6MTAwKSB7CiAgICAjIEV4dHJhY3QgVHJ1ZSBhbmQgRXhwZWN0ZWQgdmFsdWVzIGZvciB0aGUgaS10aCBwb3NpdGlvbgogICAgVHJ1ZV92YWx1ZXMgPC0gc2FwcGx5KFRydWVWYWx1ZXNfc2V0NiwgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIEV4cGVjdGVkX3ZhbHVlcyA8LSBzYXBwbHkoRXhwZWN0ZWRWYWx1ZXNfc2V0NiwgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIAogICAgIyBDYWxjdWxhdGUgdGhlIGF2ZXJhZ2Ugb2YgVHJ1ZSBhbmQgRXhwZWN0ZWQgdmFsdWVzIGZvciB0aGUgaS10aCBwb3NpdGlvbgogICAgYXZlcmFnZV90cnVlW2ksIG5dIDwtIG1lYW4oVHJ1ZV92YWx1ZXMsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfZXhwZWN0ZWRbaSwgbl0gPC0gbWVhbihFeHBlY3RlZF92YWx1ZXMsIG5hLnJtID0gVFJVRSkKICB9Cn0KCiMgQ2FsY3VsYXRlIHRoZSBvdmVyYWxsIGF2ZXJhZ2UgZm9yIGVhY2ggcG9zaXRpb24gYWNyb3NzIGFsbCBzaW11bGF0aW9ucwpvdmVyYWxsX2F2ZXJhZ2VfdHJ1ZSA8LSByb3dNZWFucyhhdmVyYWdlX3RydWUsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX2V4cGVjdGVkIDwtIHJvd01lYW5zKGF2ZXJhZ2VfZXhwZWN0ZWQsIG5hLnJtID0gVFJVRSkKCiMgUGxvdCB0aGUgb3ZlcmFsbCBhdmVyYWdlcwpwbG90KG92ZXJhbGxfYXZlcmFnZV90cnVlLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gImJsdWUiLCBtYWluID0gIk92ZXJhbGwgQXZlcmFnZSBvZiBUcnVlIHZzIEV4cGVjdGVkIFZhbHVlcyIsIHhsYWIgPSAiUG9zaXRpb24gaW4gTGlzdCIsIHlsYWIgPSAiVmFsdWUiLCB5bGltID0gYyhtaW4oYyhvdmVyYWxsX2F2ZXJhZ2VfdHJ1ZSwgb3ZlcmFsbF9hdmVyYWdlX2V4cGVjdGVkKSksIG1heChjKG92ZXJhbGxfYXZlcmFnZV90cnVlLCBvdmVyYWxsX2F2ZXJhZ2VfZXhwZWN0ZWQpKSkpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9leHBlY3RlZCwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJyZWQiKQpsZWdlbmQoInRvcHJpZ2h0IiwgbGVnZW5kID0gYygiVHJ1ZSBWYWx1ZXMiLCAiRXhwZWN0ZWQgVmFsdWVzIiksIGNvbCA9IGMoImJsdWUiLCAicmVkIiksIGx0eSA9IDEsIGNleCA9IDAuOCkKYGBgCgoKCmBgYHtyfQojIEluaXRpYWxpemUgbWF0cmljZXMgdG8gc3RvcmUgYXZlcmFnZXMgZm9yIGVhY2ggcG9zaXRpb24KYXZlcmFnZV9iaWQgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfYXNrIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQoKIyBMb29wIHRocm91Z2ggZWFjaCBzaW11bGF0aW9uIChuKQpmb3IgKG4gaW4gMToxMCkgewogICMgRXh0cmFjdCBUcnVlIHZhbHVlcyBmcm9tIHRoZSBhZ2dyZWdhdGVkX3Jlc3VsdHNfNCBkYXRhZnJhbWUKICBCaWRzX3NldDYgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzZbbiwgNF0pKSwgIiwgIikKICAKICAjIEV4dHJhY3QgRXhwZWN0ZWQgdmFsdWVzIGZyb20gdGhlIGFnZ3JlZ2F0ZWRfcmVzdWx0c180IGRhdGFmcmFtZQogIEFza3Nfc2V0NiA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfNltuLCA1XSkpLCAiLCAiKQogIAogICMgTG9vcCB0aHJvdWdoIGVhY2ggcG9zaXRpb24gKGkpCiAgZm9yIChpIGluIDE6MTAwKSB7CiAgICAjIEV4dHJhY3QgVHJ1ZSBhbmQgRXhwZWN0ZWQgdmFsdWVzIGZvciB0aGUgaS10aCBwb3NpdGlvbgogICAgQmlkcyA8LSBzYXBwbHkoQmlkc19zZXQ2LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgQXNrcyA8LSBzYXBwbHkoQXNrc19zZXQ2LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgCiAgICAjIENhbGN1bGF0ZSB0aGUgYXZlcmFnZSBvZiBUcnVlIGFuZCBFeHBlY3RlZCB2YWx1ZXMgZm9yIHRoZSBpLXRoIHBvc2l0aW9uCiAgICBhdmVyYWdlX2JpZFtpLCBuXSA8LSBtZWFuKEJpZHMsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfYXNrW2ksIG5dIDwtIG1lYW4oQXNrcywgbmEucm0gPSBUUlVFKQogIH0KfQoKIyBDYWxjdWxhdGUgdGhlIG92ZXJhbGwgYXZlcmFnZSBmb3IgZWFjaCBwb3NpdGlvbiBhY3Jvc3MgYWxsIHNpbXVsYXRpb25zCm92ZXJhbGxfYXZlcmFnZV9iaWQgPC0gcm93TWVhbnMoYXZlcmFnZV9iaWQsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX2FzayA8LSByb3dNZWFucyhhdmVyYWdlX2FzaywgbmEucm0gPSBUUlVFKQoKIyBQbG90IHRoZSBvdmVyYWxsIGF2ZXJhZ2VzCnBsb3Qob3ZlcmFsbF9hdmVyYWdlX2JpZCwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJibHVlIiwgbWFpbiA9ICJPdmVyYWxsIEF2ZXJhZ2Ugb2YgQmlkcyB2cyBBc2tzIiwgeGxhYiA9ICJQb3NpdGlvbiBpbiBMaXN0IiwgeWxhYiA9ICJWYWx1ZSIsIHlsaW0gPSBjKG1pbihjKG92ZXJhbGxfYXZlcmFnZV9iaWQsIG92ZXJhbGxfYXZlcmFnZV9hc2spKSwgbWF4KGMob3ZlcmFsbF9hdmVyYWdlX2JpZCwgb3ZlcmFsbF9hdmVyYWdlX2FzaykpKSkKbGluZXMob3ZlcmFsbF9hdmVyYWdlX2FzaywgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJyZWQiKQpsZWdlbmQoInRvcHJpZ2h0IiwgbGVnZW5kID0gYygiQmlkcyIsICJBc2tzIiksIGNvbCA9IGMoImJsdWUiLCAicmVkIiksIGx0eSA9IDEsIGNleCA9IDAuOCkKYGBgCgoKYGBge3J9CiMgSW5pdGlhbGl6ZSBtYXRyaWNlcyB0byBzdG9yZSBhdmVyYWdlcyBmb3IgZWFjaCBwb3NpdGlvbgphdmVyYWdlX2JpZCA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKYXZlcmFnZV9hc2sgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCgojIExvb3AgdGhyb3VnaCBlYWNoIHNpbXVsYXRpb24gKG4pCmZvciAobiBpbiAxOjEwKSB7CiAgIyBFeHRyYWN0IFRydWUgdmFsdWVzIGZyb20gdGhlIGFnZ3JlZ2F0ZWRfcmVzdWx0c180IGRhdGFmcmFtZQogIEJpZHNfc2V0NiA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfNltuLCA0XSkpLCAiLCAiKQogIAogICMgRXh0cmFjdCBFeHBlY3RlZCB2YWx1ZXMgZnJvbSB0aGUgYWdncmVnYXRlZF9yZXN1bHRzXzQgZGF0YWZyYW1lCiAgQXNrc19zZXQ2IDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c182W24sIDVdKSksICIsICIpCiAgCiAgIyBMb29wIHRocm91Z2ggZWFjaCBwb3NpdGlvbiAoaSkKICBmb3IgKGkgaW4gMToxMDApIHsKICAgICMgRXh0cmFjdCBUcnVlIGFuZCBFeHBlY3RlZCB2YWx1ZXMgZm9yIHRoZSBpLXRoIHBvc2l0aW9uCiAgICBCaWRzIDwtIHNhcHBseShCaWRzX3NldDYsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICBBc2tzIDwtIHNhcHBseShBc2tzX3NldDYsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICAKICAgICMgQ2FsY3VsYXRlIHRoZSBhdmVyYWdlIG9mIFRydWUgYW5kIEV4cGVjdGVkIHZhbHVlcyBmb3IgdGhlIGktdGggcG9zaXRpb24KICAgIGF2ZXJhZ2VfYmlkW2ksIG5dIDwtIG1lYW4oQmlkcywgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9hc2tbaSwgbl0gPC0gbWVhbihBc2tzLCBuYS5ybSA9IFRSVUUpCiAgfQp9CgojIENhbGN1bGF0ZSB0aGUgb3ZlcmFsbCBhdmVyYWdlIGZvciBlYWNoIHBvc2l0aW9uIGFjcm9zcyBhbGwgc2ltdWxhdGlvbnMKb3ZlcmFsbF9hdmVyYWdlX2JpZCA8LSByb3dNZWFucyhhdmVyYWdlX2JpZCwgbmEucm0gPSBUUlVFKQpvdmVyYWxsX2F2ZXJhZ2VfYXNrIDwtIHJvd01lYW5zKGF2ZXJhZ2VfYXNrLCBuYS5ybSA9IFRSVUUpCgojIyBUcnVlIFZhbHVlCiMgSW5pdGlhbGl6ZSBtYXRyaWNlcyB0byBzdG9yZSBhdmVyYWdlcyBmb3IgZWFjaCBwb3NpdGlvbgphdmVyYWdlX3RydWUgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfZXhwZWN0ZWQgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCgojIExvb3AgdGhyb3VnaCBlYWNoIHNpbXVsYXRpb24gKG4pCmZvciAobiBpbiAxOjEwKSB7CiAgIyBFeHRyYWN0IFRydWUgdmFsdWVzIGZyb20gdGhlIGFnZ3JlZ2F0ZWRfcmVzdWx0c180IGRhdGFmcmFtZQogIFRydWVWYWx1ZXNfc2V0NiA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfNltuLCAyXSkpLCAiLCAiKQogIAogICMgRXh0cmFjdCBFeHBlY3RlZCB2YWx1ZXMgZnJvbSB0aGUgYWdncmVnYXRlZF9yZXN1bHRzXzQgZGF0YWZyYW1lCiAgRXhwZWN0ZWRWYWx1ZXNfc2V0NiA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfNltuLCAzXSkpLCAiLCAiKQogIAogICMgTG9vcCB0aHJvdWdoIGVhY2ggcG9zaXRpb24gKGkpCiAgZm9yIChpIGluIDE6MTAwKSB7CiAgICAjIEV4dHJhY3QgVHJ1ZSBhbmQgRXhwZWN0ZWQgdmFsdWVzIGZvciB0aGUgaS10aCBwb3NpdGlvbgogICAgVHJ1ZV92YWx1ZXMgPC0gc2FwcGx5KFRydWVWYWx1ZXNfc2V0NiwgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIEV4cGVjdGVkX3ZhbHVlcyA8LSBzYXBwbHkoRXhwZWN0ZWRWYWx1ZXNfc2V0NiwgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIAogICAgIyBDYWxjdWxhdGUgdGhlIGF2ZXJhZ2Ugb2YgVHJ1ZSBhbmQgRXhwZWN0ZWQgdmFsdWVzIGZvciB0aGUgaS10aCBwb3NpdGlvbgogICAgYXZlcmFnZV90cnVlW2ksIG5dIDwtIG1lYW4oVHJ1ZV92YWx1ZXMsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfZXhwZWN0ZWRbaSwgbl0gPC0gbWVhbihFeHBlY3RlZF92YWx1ZXMsIG5hLnJtID0gVFJVRSkKICB9Cn0KCiMgQ2FsY3VsYXRlIHRoZSBvdmVyYWxsIGF2ZXJhZ2UgZm9yIGVhY2ggcG9zaXRpb24gYWNyb3NzIGFsbCBzaW11bGF0aW9ucwpvdmVyYWxsX2F2ZXJhZ2VfdHJ1ZSA8LSByb3dNZWFucyhhdmVyYWdlX3RydWUsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX2V4cGVjdGVkIDwtIHJvd01lYW5zKGF2ZXJhZ2VfZXhwZWN0ZWQsIG5hLnJtID0gVFJVRSkKCiMgUGxvdCB0aGUgb3ZlcmFsbCBhdmVyYWdlcwojcGxvdChvdmVyYWxsX2F2ZXJhZ2VfdHJ1ZSwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJibHVlIiwgbWFpbiA9ICJPdmVyYWxsIEF2ZXJhZ2Ugb2YgVHJ1ZSB2cyBFeHBlY3RlZCBWYWx1ZXMiLCB4bGFiID0gIlBvc2l0aW9uIGluIExpc3QiLCB5bGFiID0gIlZhbHVlIiwgeWxpbSA9IGMobWluKGMob3ZlcmFsbF9hdmVyYWdlX3RydWUsIG92ZXJhbGxfYXZlcmFnZV9leHBlY3RlZCkpLCBtYXgoYyhvdmVyYWxsX2F2ZXJhZ2VfdHJ1ZSwgb3ZlcmFsbF9hdmVyYWdlX2V4cGVjdGVkKSkpKQojbGluZXMob3ZlcmFsbF9hdmVyYWdlX2V4cGVjdGVkLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gInJlZCIpCiNsZWdlbmQoInRvcHJpZ2h0IiwgbGVnZW5kID0gYygiVHJ1ZSBWYWx1ZXMiLCAiRXhwZWN0ZWQgVmFsdWVzIiksIGNvbCA9IGMoImJsdWUiLCAicmVkIiksIGx0eSA9IDEsIGNleCA9IDAuOCkKCiMgUGxvdCB0aGUgb3ZlcmFsbCBhdmVyYWdlcwpwbG90KG92ZXJhbGxfYXZlcmFnZV9iaWQsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAiYmx1ZSIsIG1haW4gPSAiT3ZlcmFsbCBBdmVyYWdlIG9mIEJpZHMgdnMgQXNrcyAmIFRydWUgdnMgRXhwZWN0ZWQgVmFsdWVzIiwgeGxhYiA9ICJQb3NpdGlvbiBpbiBMaXN0IiwgeWxhYiA9ICJWYWx1ZSIsIHlsaW0gPSBjKG1pbihjKG92ZXJhbGxfYXZlcmFnZV9iaWQsIG92ZXJhbGxfYXZlcmFnZV9hc2ssIG92ZXJhbGxfYXZlcmFnZV90cnVlLCBvdmVyYWxsX2F2ZXJhZ2VfZXhwZWN0ZWQpKSwgbWF4KGMob3ZlcmFsbF9hdmVyYWdlX2JpZCwgb3ZlcmFsbF9hdmVyYWdlX2Fzaywgb3ZlcmFsbF9hdmVyYWdlX3RydWUsIG92ZXJhbGxfYXZlcmFnZV9leHBlY3RlZCkpKSkKbGluZXMob3ZlcmFsbF9hdmVyYWdlX2FzaywgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJyZWQiKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfdHJ1ZSwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJncmVlbiIpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9leHBlY3RlZCwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJwdXJwbGUiKQpsZWdlbmQoImJvdHRvbWxlZnQiLCBsZWdlbmQgPSBjKCJCaWRzIiwgIkFza3MiLCAiVHJ1ZSBWYWx1ZSIsICJFeHBlY3RlZCBWYWx1ZSIpLCBjb2wgPSBjKCJibHVlIiwgInJlZCIsICJncmVlbiIsICJwdXJwbGUiKSwgbHR5ID0gMSwgY2V4ID0gMC44KQpgYGAKCgpgYGB7cn0KIyBJbml0aWFsaXplIG1hdHJpY2VzIHRvIHN0b3JlIGF2ZXJhZ2VzIGZvciBlYWNoIHBvc2l0aW9uCmF2ZXJhZ2VfTU1fcG5sIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX0luZm9ybWVkX3BubCA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKYXZlcmFnZV9Ob2lzeTFfcG5sIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX05vaXN5Ml9wbmwgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfTm9pc3kzX3BubCA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKYXZlcmFnZV9Ob2lzeTRfcG5sIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX05vaXN5NV9wbmwgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCgojIExvb3AgdGhyb3VnaCBlYWNoIHNpbXVsYXRpb24gKG4pCmZvciAobiBpbiAxOjEwKSB7CgogIE1NX3BubF9zZXQ2IDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c182W24sIDZdKSksICIsICIpCgogIEluZm9ybWVkX3BubF9zZXQ2IDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c182W24sIDhdKSksICIsICIpCiAgCiAgTm9pc3kxX3BubF9zZXQ2IDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c182W24sIDEwXSkpLCAiLCAiKQogIAogIE5vaXN5Ml9wbmxfc2V0NiA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfNltuLCAxMl0pKSwgIiwgIikKICAKICBOb2lzeTNfcG5sX3NldDYgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzZbbiwgMTRdKSksICIsICIpCiAgCiAgTm9pc3k0X3BubF9zZXQ2IDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c182W24sIDE2XSkpLCAiLCAiKQogIAogIE5vaXN5NV9wbmxfc2V0NiA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfNltuLCAxOF0pKSwgIiwgIikKICAKICAjIExvb3AgdGhyb3VnaCBlYWNoIHBvc2l0aW9uIChpKQogIGZvciAoaSBpbiAxOjEwMCkgewogICAgIyBFeHRyYWN0IFRydWUgYW5kIEV4cGVjdGVkIHZhbHVlcyBmb3IgdGhlIGktdGggcG9zaXRpb24KICAgIE1NX3BubCA8LSBzYXBwbHkoTU1fcG5sX3NldDYsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICBJbmZvcm1lZF9wbmwgPC0gc2FwcGx5KEluZm9ybWVkX3BubF9zZXQ2LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgTm9pc3kxX3BubCA8LSBzYXBwbHkoTm9pc3kxX3BubF9zZXQ2LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgTm9pc3kyX3BubCA8LSBzYXBwbHkoTm9pc3kyX3BubF9zZXQ2LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgTm9pc3kzX3BubCA8LSBzYXBwbHkoTm9pc3kzX3BubF9zZXQ2LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgTm9pc3k0X3BubCA8LSBzYXBwbHkoTm9pc3k0X3BubF9zZXQ2LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgTm9pc3k1X3BubCA8LSBzYXBwbHkoTm9pc3k1X3BubF9zZXQ2LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgCiAgICAjIENhbGN1bGF0ZSB0aGUgYXZlcmFnZSBvZiBUcnVlIGFuZCBFeHBlY3RlZCB2YWx1ZXMgZm9yIHRoZSBpLXRoIHBvc2l0aW9uCiAgICBhdmVyYWdlX01NX3BubFtpLCBuXSA8LSBtZWFuKE1NX3BubCwgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9JbmZvcm1lZF9wbmxbaSwgbl0gPC0gbWVhbihJbmZvcm1lZF9wbmwsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfTm9pc3kxX3BubFtpLCBuXSA8LSBtZWFuKE5vaXN5MV9wbmwsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfTm9pc3kyX3BubFtpLCBuXSA8LSBtZWFuKE5vaXN5Ml9wbmwsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfTm9pc3kzX3BubFtpLCBuXSA8LSBtZWFuKE5vaXN5M19wbmwsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfTm9pc3k0X3BubFtpLCBuXSA8LSBtZWFuKE5vaXN5NF9wbmwsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfTm9pc3k1X3BubFtpLCBuXSA8LSBtZWFuKE5vaXN5NV9wbmwsIG5hLnJtID0gVFJVRSkKICB9Cn0KCiMgQ2FsY3VsYXRlIHRoZSBvdmVyYWxsIGF2ZXJhZ2UgZm9yIGVhY2ggcG9zaXRpb24gYWNyb3NzIGFsbCBzaW11bGF0aW9ucwpvdmVyYWxsX2F2ZXJhZ2VfTU1fcG5sIDwtIHJvd01lYW5zKGF2ZXJhZ2VfTU1fcG5sLCBuYS5ybSA9IFRSVUUpCm92ZXJhbGxfYXZlcmFnZV9JbmZvcm1lZF9wbmwgPC0gcm93TWVhbnMoYXZlcmFnZV9JbmZvcm1lZF9wbmwsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX05vaXN5MV9wbmwgPC0gcm93TWVhbnMoYXZlcmFnZV9Ob2lzeTFfcG5sLCBuYS5ybSA9IFRSVUUpCm92ZXJhbGxfYXZlcmFnZV9Ob2lzeTJfcG5sIDwtIHJvd01lYW5zKGF2ZXJhZ2VfTm9pc3kyX3BubCwgbmEucm0gPSBUUlVFKQpvdmVyYWxsX2F2ZXJhZ2VfTm9pc3kzX3BubCA8LSByb3dNZWFucyhhdmVyYWdlX05vaXN5M19wbmwsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX05vaXN5NF9wbmwgPC0gcm93TWVhbnMoYXZlcmFnZV9Ob2lzeTRfcG5sLCBuYS5ybSA9IFRSVUUpCm92ZXJhbGxfYXZlcmFnZV9Ob2lzeTVfcG5sIDwtIHJvd01lYW5zKGF2ZXJhZ2VfTm9pc3k1X3BubCwgbmEucm0gPSBUUlVFKQoKIyBQbG90IHRoZSBvdmVyYWxsIGF2ZXJhZ2VzCnBsb3Qob3ZlcmFsbF9hdmVyYWdlX01NX3BubCwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJibGFjayIsIG1haW4gPSAiT3ZlcmFsbCBBdmVyYWdlIFBOTCIsIHhsYWIgPSAiUG9zaXRpb24gaW4gTGlzdCIsIHlsYWIgPSAiVmFsdWUiLCB5bGltID0gYyhtaW4oYyhvdmVyYWxsX2F2ZXJhZ2VfTU1fcG5sLCBvdmVyYWxsX2F2ZXJhZ2VfSW5mb3JtZWRfcG5sLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3kxX3BubCwgb3ZlcmFsbF9hdmVyYWdlX05vaXN5Ml9wbmwsIG92ZXJhbGxfYXZlcmFnZV9Ob2lzeTNfcG5sLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3k0X3BubCwgb3ZlcmFsbF9hdmVyYWdlX05vaXN5NV9wbmwpKSwgbWF4KGMob3ZlcmFsbF9hdmVyYWdlX01NX3BubCwgb3ZlcmFsbF9hdmVyYWdlX0luZm9ybWVkX3BubCwgb3ZlcmFsbF9hdmVyYWdlX05vaXN5MV9wbmwsIG92ZXJhbGxfYXZlcmFnZV9Ob2lzeTJfcG5sLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3kzX3BubCwgb3ZlcmFsbF9hdmVyYWdlX05vaXN5NF9wbmwsIG92ZXJhbGxfYXZlcmFnZV9Ob2lzeTVfcG5sKSkpKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfSW5mb3JtZWRfcG5sLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gInJlZCIpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9Ob2lzeTFfcG5sLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gImdyZWVuIikKbGluZXMob3ZlcmFsbF9hdmVyYWdlX05vaXN5Ml9wbmwsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAieWVsbG93IikKbGluZXMob3ZlcmFsbF9hdmVyYWdlX05vaXN5M19wbmwsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAiYmx1ZSIpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9Ob2lzeTRfcG5sLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gInB1cnBsZSIpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9Ob2lzeTVfcG5sLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gIm9yYW5nZSIpCgojIEFkZCBsZWdlbmQKbGVnZW5kKCJib3R0b21sZWZ0IiwgbGVnZW5kID0gYygiTWFya2V0IE1ha2VyIiwgIkluZm9ybWVkIiwgIk5vaXN5IDEiLCAiTm9pc3kgMiIsICJOb2lzeSAzIiwgIk5vaXN5IDQiLCAiTm9pc3kgNSIpLCBjb2wgPSBjKCJibGFjayIsICJyZWQiLCAiZ3JlZW4iLCAieWVsbG93IiwgImJsdWUiLCAicHVycGxlIiwgIm9yYW5nZSIpLCBsdHkgPSAxLCBjZXggPSAwLjgpCmBgYAoKCmBgYHtyfQojIEluaXRpYWxpemUgbWF0cmljZXMgdG8gc3RvcmUgYXZlcmFnZXMgZm9yIGVhY2ggcG9zaXRpb24KYXZlcmFnZV9NTV9wb3MgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfSW5mb3JtZWRfcG9zIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX05vaXN5MV9wb3MgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfTm9pc3kyX3BvcyA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKYXZlcmFnZV9Ob2lzeTNfcG9zIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX05vaXN5NF9wb3MgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfTm9pc3k1X3BvcyA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKCiMgTG9vcCB0aHJvdWdoIGVhY2ggc2ltdWxhdGlvbiAobikKZm9yIChuIGluIDE6MTApIHsKCiAgTU1fcG9zX3NldDYgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzZbbiwgN10pKSwgIiwgIikKCiAgSW5mb3JtZWRfcG9zX3NldDYgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzZbbiwgOV0pKSwgIiwgIikKICAKICBOb2lzeTFfcG9zX3NldDYgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzZbbiwgMTFdKSksICIsICIpCiAgCiAgTm9pc3kyX3Bvc19zZXQ2IDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c182W24sIDEzXSkpLCAiLCAiKQogIAogIE5vaXN5M19wb3Nfc2V0NiA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfNltuLCAxNV0pKSwgIiwgIikKICAKICBOb2lzeTRfcG9zX3NldDYgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzZbbiwgMTddKSksICIsICIpCiAgCiAgTm9pc3k1X3Bvc19zZXQ2IDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c182W24sIDE5XSkpLCAiLCAiKQogIAogICMgTG9vcCB0aHJvdWdoIGVhY2ggcG9zaXRpb24gKGkpCiAgZm9yIChpIGluIDE6MTAwKSB7CiAgICAjIEV4dHJhY3QgVHJ1ZSBhbmQgRXhwZWN0ZWQgdmFsdWVzIGZvciB0aGUgaS10aCBwb3NpdGlvbgogICAgTU1fcG9zIDwtIHNhcHBseShNTV9wb3Nfc2V0NiwgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIEluZm9ybWVkX3BvcyA8LSBzYXBwbHkoSW5mb3JtZWRfcG5sX3NldDYsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICBOb2lzeTFfcG9zIDwtIHNhcHBseShOb2lzeTFfcG9zX3NldDYsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICBOb2lzeTJfcG9zIDwtIHNhcHBseShOb2lzeTJfcG9zX3NldDYsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICBOb2lzeTNfcG9zIDwtIHNhcHBseShOb2lzeTNfcG9zX3NldDYsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICBOb2lzeTRfcG9zIDwtIHNhcHBseShOb2lzeTRfcG9zX3NldDYsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICBOb2lzeTVfcG9zIDwtIHNhcHBseShOb2lzeTVfcG9zX3NldDYsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICAKICAgICMgQ2FsY3VsYXRlIHRoZSBhdmVyYWdlIG9mIFRydWUgYW5kIEV4cGVjdGVkIHZhbHVlcyBmb3IgdGhlIGktdGggcG9zaXRpb24KICAgIGF2ZXJhZ2VfTU1fcG9zW2ksIG5dIDwtIG1lYW4oTU1fcG9zLCBuYS5ybSA9IFRSVUUpCiAgICBhdmVyYWdlX0luZm9ybWVkX3Bvc1tpLCBuXSA8LSBtZWFuKEluZm9ybWVkX3BvcywgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9Ob2lzeTFfcG9zW2ksIG5dIDwtIG1lYW4oTm9pc3kxX3BvcywgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9Ob2lzeTJfcG9zW2ksIG5dIDwtIG1lYW4oTm9pc3kyX3BvcywgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9Ob2lzeTNfcG9zW2ksIG5dIDwtIG1lYW4oTm9pc3kzX3BvcywgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9Ob2lzeTRfcG9zW2ksIG5dIDwtIG1lYW4oTm9pc3k0X3BvcywgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9Ob2lzeTVfcG9zW2ksIG5dIDwtIG1lYW4oTm9pc3k1X3BvcywgbmEucm0gPSBUUlVFKQogIH0KfQoKIyBDYWxjdWxhdGUgdGhlIG92ZXJhbGwgYXZlcmFnZSBmb3IgZWFjaCBwb3NpdGlvbiBhY3Jvc3MgYWxsIHNpbXVsYXRpb25zCm92ZXJhbGxfYXZlcmFnZV9NTV9wb3MgPC0gcm93TWVhbnMoYXZlcmFnZV9NTV9wb3MsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX0luZm9ybWVkX3BvcyA8LSByb3dNZWFucyhhdmVyYWdlX0luZm9ybWVkX3BvcywgbmEucm0gPSBUUlVFKQpvdmVyYWxsX2F2ZXJhZ2VfTm9pc3kxX3BvcyA8LSByb3dNZWFucyhhdmVyYWdlX05vaXN5MV9wb3MsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX05vaXN5Ml9wb3MgPC0gcm93TWVhbnMoYXZlcmFnZV9Ob2lzeTJfcG9zLCBuYS5ybSA9IFRSVUUpCm92ZXJhbGxfYXZlcmFnZV9Ob2lzeTNfcG9zIDwtIHJvd01lYW5zKGF2ZXJhZ2VfTm9pc3kzX3BvcywgbmEucm0gPSBUUlVFKQpvdmVyYWxsX2F2ZXJhZ2VfTm9pc3k0X3BvcyA8LSByb3dNZWFucyhhdmVyYWdlX05vaXN5NF9wb3MsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX05vaXN5NV9wb3MgPC0gcm93TWVhbnMoYXZlcmFnZV9Ob2lzeTVfcG9zLCBuYS5ybSA9IFRSVUUpCgojIFBsb3QgdGhlIG92ZXJhbGwgYXZlcmFnZXMKcGxvdChvdmVyYWxsX2F2ZXJhZ2VfTU1fcG9zLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gImJsYWNrIiwgbWFpbiA9ICJPdmVyYWxsIEF2ZXJhZ2UgUG9zaXRpb24iLCB4bGFiID0gIlBvc2l0aW9uIGluIExpc3QiLCB5bGFiID0gIlZhbHVlIiwgeWxpbSA9IGMobWluKGMob3ZlcmFsbF9hdmVyYWdlX01NX3Bvcywgb3ZlcmFsbF9hdmVyYWdlX0luZm9ybWVkX3Bvcywgb3ZlcmFsbF9hdmVyYWdlX05vaXN5MV9wb3MsIG92ZXJhbGxfYXZlcmFnZV9Ob2lzeTJfcG9zLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3kzX3Bvcywgb3ZlcmFsbF9hdmVyYWdlX05vaXN5NF9wb3MsIG92ZXJhbGxfYXZlcmFnZV9Ob2lzeTVfcG9zKSksIG1heChjKG92ZXJhbGxfYXZlcmFnZV9NTV9wb3MsIG92ZXJhbGxfYXZlcmFnZV9JbmZvcm1lZF9wb3MsIG92ZXJhbGxfYXZlcmFnZV9Ob2lzeTFfcG9zLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3kyX3Bvcywgb3ZlcmFsbF9hdmVyYWdlX05vaXN5M19wb3MsIG92ZXJhbGxfYXZlcmFnZV9Ob2lzeTRfcG9zLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3k1X3BvcykpKSkKbGluZXMob3ZlcmFsbF9hdmVyYWdlX0luZm9ybWVkX3BvcywgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJyZWQiKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfTm9pc3kxX3BvcywgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJncmVlbiIpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9Ob2lzeTJfcG9zLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gInllbGxvdyIpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9Ob2lzeTNfcG9zLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gImJsdWUiKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfTm9pc3k0X3BvcywgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJwdXJwbGUiKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfTm9pc3k1X3BvcywgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJvcmFuZ2UiKQoKIyBBZGQgbGVnZW5kCmxlZ2VuZCgiYm90dG9tbGVmdCIsIGxlZ2VuZCA9IGMoIk1hcmtldCBNYWtlciIsICJJbmZvcm1lZCIsICJOb2lzeSAxIiwgIk5vaXN5IDIiLCAiTm9pc3kgMyIsICJOb2lzeSA0IiwgIk5vaXN5IDUiKSwgY29sID0gYygiYmxhY2siLCAicmVkIiwgImdyZWVuIiwgInllbGxvdyIsICJibHVlIiwgInB1cnBsZSIsICJvcmFuZ2UiKSwgbHR5ID0gMSwgY2V4ID0gMC44KQpgYGAKCgojIyBzZXQ3ICgxIGluZm9ybWVkICsgNSBub2lzeSBpbmZvcm1lZCkKCmBgYHtyfQojIEluaXRpYWxpemUgbWF0cmljZXMgdG8gc3RvcmUgYXZlcmFnZXMgZm9yIGVhY2ggcG9zaXRpb24KYXZlcmFnZV90cnVlIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX2V4cGVjdGVkIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQoKIyBMb29wIHRocm91Z2ggZWFjaCBzaW11bGF0aW9uIChuKQpmb3IgKG4gaW4gMToxMCkgewogICMgRXh0cmFjdCBUcnVlIHZhbHVlcyBmcm9tIHRoZSBhZ2dyZWdhdGVkX3Jlc3VsdHNfNCBkYXRhZnJhbWUKICBUcnVlVmFsdWVzX3NldDcgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzdbbiwgMl0pKSwgIiwgIikKICAKICAjIEV4dHJhY3QgRXhwZWN0ZWQgdmFsdWVzIGZyb20gdGhlIGFnZ3JlZ2F0ZWRfcmVzdWx0c180IGRhdGFmcmFtZQogIEV4cGVjdGVkVmFsdWVzX3NldDcgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzdbbiwgM10pKSwgIiwgIikKICAKICAjIExvb3AgdGhyb3VnaCBlYWNoIHBvc2l0aW9uIChpKQogIGZvciAoaSBpbiAxOjEwMCkgewogICAgIyBFeHRyYWN0IFRydWUgYW5kIEV4cGVjdGVkIHZhbHVlcyBmb3IgdGhlIGktdGggcG9zaXRpb24KICAgIFRydWVfdmFsdWVzIDwtIHNhcHBseShUcnVlVmFsdWVzX3NldDcsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICBFeHBlY3RlZF92YWx1ZXMgPC0gc2FwcGx5KEV4cGVjdGVkVmFsdWVzX3NldDcsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICAKICAgICMgQ2FsY3VsYXRlIHRoZSBhdmVyYWdlIG9mIFRydWUgYW5kIEV4cGVjdGVkIHZhbHVlcyBmb3IgdGhlIGktdGggcG9zaXRpb24KICAgIGF2ZXJhZ2VfdHJ1ZVtpLCBuXSA8LSBtZWFuKFRydWVfdmFsdWVzLCBuYS5ybSA9IFRSVUUpCiAgICBhdmVyYWdlX2V4cGVjdGVkW2ksIG5dIDwtIG1lYW4oRXhwZWN0ZWRfdmFsdWVzLCBuYS5ybSA9IFRSVUUpCiAgfQp9CgojIENhbGN1bGF0ZSB0aGUgb3ZlcmFsbCBhdmVyYWdlIGZvciBlYWNoIHBvc2l0aW9uIGFjcm9zcyBhbGwgc2ltdWxhdGlvbnMKb3ZlcmFsbF9hdmVyYWdlX3RydWUgPC0gcm93TWVhbnMoYXZlcmFnZV90cnVlLCBuYS5ybSA9IFRSVUUpCm92ZXJhbGxfYXZlcmFnZV9leHBlY3RlZCA8LSByb3dNZWFucyhhdmVyYWdlX2V4cGVjdGVkLCBuYS5ybSA9IFRSVUUpCgojIFBsb3QgdGhlIG92ZXJhbGwgYXZlcmFnZXMKcGxvdChvdmVyYWxsX2F2ZXJhZ2VfdHJ1ZSwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJibHVlIiwgbWFpbiA9ICJPdmVyYWxsIEF2ZXJhZ2Ugb2YgVHJ1ZSB2cyBFeHBlY3RlZCBWYWx1ZXMiLCB4bGFiID0gIlBvc2l0aW9uIGluIExpc3QiLCB5bGFiID0gIlZhbHVlIiwgeWxpbSA9IGMobWluKGMob3ZlcmFsbF9hdmVyYWdlX3RydWUsIG92ZXJhbGxfYXZlcmFnZV9leHBlY3RlZCkpLCBtYXgoYyhvdmVyYWxsX2F2ZXJhZ2VfdHJ1ZSwgb3ZlcmFsbF9hdmVyYWdlX2V4cGVjdGVkKSkpKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfZXhwZWN0ZWQsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAicmVkIikKbGVnZW5kKCJ0b3ByaWdodCIsIGxlZ2VuZCA9IGMoIlRydWUgVmFsdWVzIiwgIkV4cGVjdGVkIFZhbHVlcyIpLCBjb2wgPSBjKCJibHVlIiwgInJlZCIpLCBsdHkgPSAxLCBjZXggPSAwLjgpCmBgYAoKCmBgYHtyfQojIEluaXRpYWxpemUgbWF0cmljZXMgdG8gc3RvcmUgYXZlcmFnZXMgZm9yIGVhY2ggcG9zaXRpb24KYXZlcmFnZV9iaWQgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfYXNrIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQoKIyBMb29wIHRocm91Z2ggZWFjaCBzaW11bGF0aW9uIChuKQpmb3IgKG4gaW4gMToxMCkgewogICMgRXh0cmFjdCBUcnVlIHZhbHVlcyBmcm9tIHRoZSBhZ2dyZWdhdGVkX3Jlc3VsdHNfNCBkYXRhZnJhbWUKICBCaWRzX3NldDcgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzdbbiwgNF0pKSwgIiwgIikKICAKICAjIEV4dHJhY3QgRXhwZWN0ZWQgdmFsdWVzIGZyb20gdGhlIGFnZ3JlZ2F0ZWRfcmVzdWx0c180IGRhdGFmcmFtZQogIEFza3Nfc2V0NyA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfN1tuLCA1XSkpLCAiLCAiKQogIAogICMgTG9vcCB0aHJvdWdoIGVhY2ggcG9zaXRpb24gKGkpCiAgZm9yIChpIGluIDE6MTAwKSB7CiAgICAjIEV4dHJhY3QgVHJ1ZSBhbmQgRXhwZWN0ZWQgdmFsdWVzIGZvciB0aGUgaS10aCBwb3NpdGlvbgogICAgQmlkcyA8LSBzYXBwbHkoQmlkc19zZXQ3LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgQXNrcyA8LSBzYXBwbHkoQXNrc19zZXQ3LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgCiAgICAjIENhbGN1bGF0ZSB0aGUgYXZlcmFnZSBvZiBUcnVlIGFuZCBFeHBlY3RlZCB2YWx1ZXMgZm9yIHRoZSBpLXRoIHBvc2l0aW9uCiAgICBhdmVyYWdlX2JpZFtpLCBuXSA8LSBtZWFuKEJpZHMsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfYXNrW2ksIG5dIDwtIG1lYW4oQXNrcywgbmEucm0gPSBUUlVFKQogIH0KfQoKIyBDYWxjdWxhdGUgdGhlIG92ZXJhbGwgYXZlcmFnZSBmb3IgZWFjaCBwb3NpdGlvbiBhY3Jvc3MgYWxsIHNpbXVsYXRpb25zCm92ZXJhbGxfYXZlcmFnZV9iaWQgPC0gcm93TWVhbnMoYXZlcmFnZV9iaWQsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX2FzayA8LSByb3dNZWFucyhhdmVyYWdlX2FzaywgbmEucm0gPSBUUlVFKQoKIyBQbG90IHRoZSBvdmVyYWxsIGF2ZXJhZ2VzCnBsb3Qob3ZlcmFsbF9hdmVyYWdlX2JpZCwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJibHVlIiwgbWFpbiA9ICJPdmVyYWxsIEF2ZXJhZ2Ugb2YgQmlkcyB2cyBBc2tzIiwgeGxhYiA9ICJQb3NpdGlvbiBpbiBMaXN0IiwgeWxhYiA9ICJWYWx1ZSIsIHlsaW0gPSBjKG1pbihjKG92ZXJhbGxfYXZlcmFnZV9iaWQsIG92ZXJhbGxfYXZlcmFnZV9hc2spKSwgbWF4KGMob3ZlcmFsbF9hdmVyYWdlX2JpZCwgb3ZlcmFsbF9hdmVyYWdlX2FzaykpKSkKbGluZXMob3ZlcmFsbF9hdmVyYWdlX2FzaywgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJyZWQiKQpsZWdlbmQoInRvcHJpZ2h0IiwgbGVnZW5kID0gYygiQmlkcyIsICJBc2tzIiksIGNvbCA9IGMoImJsdWUiLCAicmVkIiksIGx0eSA9IDEsIGNleCA9IDAuOCkKYGBgCgpgYGB7cn0KIyBJbml0aWFsaXplIG1hdHJpY2VzIHRvIHN0b3JlIGF2ZXJhZ2VzIGZvciBlYWNoIHBvc2l0aW9uCmF2ZXJhZ2VfYmlkIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX2FzayA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKCiMgTG9vcCB0aHJvdWdoIGVhY2ggc2ltdWxhdGlvbiAobikKZm9yIChuIGluIDE6MTApIHsKICAjIEV4dHJhY3QgVHJ1ZSB2YWx1ZXMgZnJvbSB0aGUgYWdncmVnYXRlZF9yZXN1bHRzXzQgZGF0YWZyYW1lCiAgQmlkc19zZXQ3IDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c183W24sIDRdKSksICIsICIpCiAgCiAgIyBFeHRyYWN0IEV4cGVjdGVkIHZhbHVlcyBmcm9tIHRoZSBhZ2dyZWdhdGVkX3Jlc3VsdHNfNCBkYXRhZnJhbWUKICBBc2tzX3NldDcgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzdbbiwgNV0pKSwgIiwgIikKICAKICAjIExvb3AgdGhyb3VnaCBlYWNoIHBvc2l0aW9uIChpKQogIGZvciAoaSBpbiAxOjEwMCkgewogICAgIyBFeHRyYWN0IFRydWUgYW5kIEV4cGVjdGVkIHZhbHVlcyBmb3IgdGhlIGktdGggcG9zaXRpb24KICAgIEJpZHMgPC0gc2FwcGx5KEJpZHNfc2V0NywgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIEFza3MgPC0gc2FwcGx5KEFza3Nfc2V0NywgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIAogICAgIyBDYWxjdWxhdGUgdGhlIGF2ZXJhZ2Ugb2YgVHJ1ZSBhbmQgRXhwZWN0ZWQgdmFsdWVzIGZvciB0aGUgaS10aCBwb3NpdGlvbgogICAgYXZlcmFnZV9iaWRbaSwgbl0gPC0gbWVhbihCaWRzLCBuYS5ybSA9IFRSVUUpCiAgICBhdmVyYWdlX2Fza1tpLCBuXSA8LSBtZWFuKEFza3MsIG5hLnJtID0gVFJVRSkKICB9Cn0KCiMgQ2FsY3VsYXRlIHRoZSBvdmVyYWxsIGF2ZXJhZ2UgZm9yIGVhY2ggcG9zaXRpb24gYWNyb3NzIGFsbCBzaW11bGF0aW9ucwpvdmVyYWxsX2F2ZXJhZ2VfYmlkIDwtIHJvd01lYW5zKGF2ZXJhZ2VfYmlkLCBuYS5ybSA9IFRSVUUpCm92ZXJhbGxfYXZlcmFnZV9hc2sgPC0gcm93TWVhbnMoYXZlcmFnZV9hc2ssIG5hLnJtID0gVFJVRSkKCiMjIFRydWUgVmFsdWUKIyBJbml0aWFsaXplIG1hdHJpY2VzIHRvIHN0b3JlIGF2ZXJhZ2VzIGZvciBlYWNoIHBvc2l0aW9uCmF2ZXJhZ2VfdHJ1ZSA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKYXZlcmFnZV9leHBlY3RlZCA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKCiMgTG9vcCB0aHJvdWdoIGVhY2ggc2ltdWxhdGlvbiAobikKZm9yIChuIGluIDE6MTApIHsKICAjIEV4dHJhY3QgVHJ1ZSB2YWx1ZXMgZnJvbSB0aGUgYWdncmVnYXRlZF9yZXN1bHRzXzQgZGF0YWZyYW1lCiAgVHJ1ZVZhbHVlc19zZXQ3IDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c183W24sIDJdKSksICIsICIpCiAgCiAgIyBFeHRyYWN0IEV4cGVjdGVkIHZhbHVlcyBmcm9tIHRoZSBhZ2dyZWdhdGVkX3Jlc3VsdHNfNCBkYXRhZnJhbWUKICBFeHBlY3RlZFZhbHVlc19zZXQ3IDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c183W24sIDNdKSksICIsICIpCiAgCiAgIyBMb29wIHRocm91Z2ggZWFjaCBwb3NpdGlvbiAoaSkKICBmb3IgKGkgaW4gMToxMDApIHsKICAgICMgRXh0cmFjdCBUcnVlIGFuZCBFeHBlY3RlZCB2YWx1ZXMgZm9yIHRoZSBpLXRoIHBvc2l0aW9uCiAgICBUcnVlX3ZhbHVlcyA8LSBzYXBwbHkoVHJ1ZVZhbHVlc19zZXQ3LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgRXhwZWN0ZWRfdmFsdWVzIDwtIHNhcHBseShFeHBlY3RlZFZhbHVlc19zZXQ3LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgCiAgICAjIENhbGN1bGF0ZSB0aGUgYXZlcmFnZSBvZiBUcnVlIGFuZCBFeHBlY3RlZCB2YWx1ZXMgZm9yIHRoZSBpLXRoIHBvc2l0aW9uCiAgICBhdmVyYWdlX3RydWVbaSwgbl0gPC0gbWVhbihUcnVlX3ZhbHVlcywgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9leHBlY3RlZFtpLCBuXSA8LSBtZWFuKEV4cGVjdGVkX3ZhbHVlcywgbmEucm0gPSBUUlVFKQogIH0KfQoKIyBDYWxjdWxhdGUgdGhlIG92ZXJhbGwgYXZlcmFnZSBmb3IgZWFjaCBwb3NpdGlvbiBhY3Jvc3MgYWxsIHNpbXVsYXRpb25zCm92ZXJhbGxfYXZlcmFnZV90cnVlIDwtIHJvd01lYW5zKGF2ZXJhZ2VfdHJ1ZSwgbmEucm0gPSBUUlVFKQpvdmVyYWxsX2F2ZXJhZ2VfZXhwZWN0ZWQgPC0gcm93TWVhbnMoYXZlcmFnZV9leHBlY3RlZCwgbmEucm0gPSBUUlVFKQoKIyBQbG90IHRoZSBvdmVyYWxsIGF2ZXJhZ2VzCiNwbG90KG92ZXJhbGxfYXZlcmFnZV90cnVlLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gImJsdWUiLCBtYWluID0gIk92ZXJhbGwgQXZlcmFnZSBvZiBUcnVlIHZzIEV4cGVjdGVkIFZhbHVlcyIsIHhsYWIgPSAiUG9zaXRpb24gaW4gTGlzdCIsIHlsYWIgPSAiVmFsdWUiLCB5bGltID0gYyhtaW4oYyhvdmVyYWxsX2F2ZXJhZ2VfdHJ1ZSwgb3ZlcmFsbF9hdmVyYWdlX2V4cGVjdGVkKSksIG1heChjKG92ZXJhbGxfYXZlcmFnZV90cnVlLCBvdmVyYWxsX2F2ZXJhZ2VfZXhwZWN0ZWQpKSkpCiNsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfZXhwZWN0ZWQsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAicmVkIikKI2xlZ2VuZCgidG9wcmlnaHQiLCBsZWdlbmQgPSBjKCJUcnVlIFZhbHVlcyIsICJFeHBlY3RlZCBWYWx1ZXMiKSwgY29sID0gYygiYmx1ZSIsICJyZWQiKSwgbHR5ID0gMSwgY2V4ID0gMC44KQoKIyBQbG90IHRoZSBvdmVyYWxsIGF2ZXJhZ2VzCnBsb3Qob3ZlcmFsbF9hdmVyYWdlX2JpZCwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJibHVlIiwgbWFpbiA9ICJPdmVyYWxsIEF2ZXJhZ2Ugb2YgQmlkcyB2cyBBc2tzICYgVHJ1ZSB2cyBFeHBlY3RlZCBWYWx1ZXMiLCB4bGFiID0gIlBvc2l0aW9uIGluIExpc3QiLCB5bGFiID0gIlZhbHVlIiwgeWxpbSA9IGMobWluKGMob3ZlcmFsbF9hdmVyYWdlX2JpZCwgb3ZlcmFsbF9hdmVyYWdlX2Fzaywgb3ZlcmFsbF9hdmVyYWdlX3RydWUsIG92ZXJhbGxfYXZlcmFnZV9leHBlY3RlZCkpLCBtYXgoYyhvdmVyYWxsX2F2ZXJhZ2VfYmlkLCBvdmVyYWxsX2F2ZXJhZ2VfYXNrLCBvdmVyYWxsX2F2ZXJhZ2VfdHJ1ZSwgb3ZlcmFsbF9hdmVyYWdlX2V4cGVjdGVkKSkpKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfYXNrLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gInJlZCIpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV90cnVlLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gImdyZWVuIikKbGluZXMob3ZlcmFsbF9hdmVyYWdlX2V4cGVjdGVkLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gInB1cnBsZSIpCmxlZ2VuZCgiYm90dG9tbGVmdCIsIGxlZ2VuZCA9IGMoIkJpZHMiLCAiQXNrcyIsICJUcnVlIFZhbHVlIiwgIkV4cGVjdGVkIFZhbHVlIiksIGNvbCA9IGMoImJsdWUiLCAicmVkIiwgImdyZWVuIiwgInB1cnBsZSIpLCBsdHkgPSAxLCBjZXggPSAwLjgpCmBgYAoKCmBgYHtyfQojIEluaXRpYWxpemUgbWF0cmljZXMgdG8gc3RvcmUgYXZlcmFnZXMgZm9yIGVhY2ggcG9zaXRpb24KYXZlcmFnZV9NTV9wbmwgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfSW5mb3JtZWRfcG5sIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX05vaXN5SW5mb3JtZWQxX3BubCA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKYXZlcmFnZV9Ob2lzeUluZm9ybWVkMl9wbmwgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfTm9pc3lJbmZvcm1lZDNfcG5sIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX05vaXN5SW5mb3JtZWQ0X3BubCA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKYXZlcmFnZV9Ob2lzeUluZm9ybWVkNV9wbmwgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCgojIExvb3AgdGhyb3VnaCBlYWNoIHNpbXVsYXRpb24gKG4pCmZvciAobiBpbiAxOjEwKSB7CgogIE1NX3BubF9zZXQ3IDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c183W24sIDZdKSksICIsICIpCgogIEluZm9ybWVkX3BubF9zZXQ3IDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c183W24sIDhdKSksICIsICIpCiAgCiAgTm9pc3lJbmZvcm1lZDFfcG5sX3NldDcgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzdbbiwgMTBdKSksICIsICIpCiAgCiAgTm9pc3lJbmZvcm1lZDJfcG5sX3NldDcgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzdbbiwgMTJdKSksICIsICIpCiAgCiAgTm9pc3lJbmZvcm1lZDNfcG5sX3NldDcgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzdbbiwgMTRdKSksICIsICIpCiAgCiAgTm9pc3lJbmZvcm1lZDRfcG5sX3NldDcgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzdbbiwgMTZdKSksICIsICIpCiAgCiAgTm9pc3lJbmZvcm1lZDVfcG5sX3NldDcgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzdbbiwgMThdKSksICIsICIpCiAgCiAgIyBMb29wIHRocm91Z2ggZWFjaCBwb3NpdGlvbiAoaSkKICBmb3IgKGkgaW4gMToxMDApIHsKICAgICMgRXh0cmFjdCBUcnVlIGFuZCBFeHBlY3RlZCB2YWx1ZXMgZm9yIHRoZSBpLXRoIHBvc2l0aW9uCiAgICBNTV9wbmwgPC0gc2FwcGx5KE1NX3BubF9zZXQ3LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgSW5mb3JtZWRfcG5sIDwtIHNhcHBseShJbmZvcm1lZF9wbmxfc2V0NywgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIE5vaXN5SW5mb3JtZWQxX3BubCA8LSBzYXBwbHkoTm9pc3lJbmZvcm1lZDFfcG5sX3NldDcsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICBOb2lzeUluZm9ybWVkMl9wbmwgPC0gc2FwcGx5KE5vaXN5SW5mb3JtZWQyX3BubF9zZXQ3LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgTm9pc3lJbmZvcm1lZDNfcG5sIDwtIHNhcHBseShOb2lzeUluZm9ybWVkM19wbmxfc2V0NywgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIE5vaXN5SW5mb3JtZWQ0X3BubCA8LSBzYXBwbHkoTm9pc3lJbmZvcm1lZDRfcG5sX3NldDcsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICBOb2lzeUluZm9ybWVkNV9wbmwgPC0gc2FwcGx5KE5vaXN5SW5mb3JtZWQ1X3BubF9zZXQ3LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgCiAgICAjIENhbGN1bGF0ZSB0aGUgYXZlcmFnZSBvZiBUcnVlIGFuZCBFeHBlY3RlZCB2YWx1ZXMgZm9yIHRoZSBpLXRoIHBvc2l0aW9uCiAgICBhdmVyYWdlX01NX3BubFtpLCBuXSA8LSBtZWFuKE1NX3BubCwgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9JbmZvcm1lZF9wbmxbaSwgbl0gPC0gbWVhbihJbmZvcm1lZF9wbmwsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfTm9pc3lJbmZvcm1lZDFfcG5sW2ksIG5dIDwtIG1lYW4oTm9pc3lJbmZvcm1lZDFfcG5sLCBuYS5ybSA9IFRSVUUpCiAgICBhdmVyYWdlX05vaXN5SW5mb3JtZWQyX3BubFtpLCBuXSA8LSBtZWFuKE5vaXN5SW5mb3JtZWQyX3BubCwgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9Ob2lzeUluZm9ybWVkM19wbmxbaSwgbl0gPC0gbWVhbihOb2lzeUluZm9ybWVkM19wbmwsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfTm9pc3lJbmZvcm1lZDRfcG5sW2ksIG5dIDwtIG1lYW4oTm9pc3lJbmZvcm1lZDRfcG5sLCBuYS5ybSA9IFRSVUUpCiAgICBhdmVyYWdlX05vaXN5SW5mb3JtZWQ1X3BubFtpLCBuXSA8LSBtZWFuKE5vaXN5SW5mb3JtZWQ1X3BubCwgbmEucm0gPSBUUlVFKQogIH0KfQoKIyBDYWxjdWxhdGUgdGhlIG92ZXJhbGwgYXZlcmFnZSBmb3IgZWFjaCBwb3NpdGlvbiBhY3Jvc3MgYWxsIHNpbXVsYXRpb25zCm92ZXJhbGxfYXZlcmFnZV9NTV9wbmwgPC0gcm93TWVhbnMoYXZlcmFnZV9NTV9wbmwsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX0luZm9ybWVkX3BubCA8LSByb3dNZWFucyhhdmVyYWdlX0luZm9ybWVkX3BubCwgbmEucm0gPSBUUlVFKQpvdmVyYWxsX2F2ZXJhZ2VfTm9pc3lJbmZvcm1lZDFfcG5sIDwtIHJvd01lYW5zKGF2ZXJhZ2VfTm9pc3lJbmZvcm1lZDFfcG5sLCBuYS5ybSA9IFRSVUUpCm92ZXJhbGxfYXZlcmFnZV9Ob2lzeUluZm9ybWVkMl9wbmwgPC0gcm93TWVhbnMoYXZlcmFnZV9Ob2lzeUluZm9ybWVkMl9wbmwsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX05vaXN5SW5mb3JtZWQzX3BubCA8LSByb3dNZWFucyhhdmVyYWdlX05vaXN5SW5mb3JtZWQzX3BubCwgbmEucm0gPSBUUlVFKQpvdmVyYWxsX2F2ZXJhZ2VfTm9pc3lJbmZvcm1lZDRfcG5sIDwtIHJvd01lYW5zKGF2ZXJhZ2VfTm9pc3lJbmZvcm1lZDRfcG5sLCBuYS5ybSA9IFRSVUUpCm92ZXJhbGxfYXZlcmFnZV9Ob2lzeUluZm9ybWVkNV9wbmwgPC0gcm93TWVhbnMoYXZlcmFnZV9Ob2lzeUluZm9ybWVkNV9wbmwsIG5hLnJtID0gVFJVRSkKCiMgUGxvdCB0aGUgb3ZlcmFsbCBhdmVyYWdlcwpwbG90KG92ZXJhbGxfYXZlcmFnZV9NTV9wbmwsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAiYmxhY2siLCBtYWluID0gIk92ZXJhbGwgQXZlcmFnZSBQTkwiLCB4bGFiID0gIlBvc2l0aW9uIGluIExpc3QiLCB5bGFiID0gIlZhbHVlIiwgeWxpbSA9IGMobWluKGMob3ZlcmFsbF9hdmVyYWdlX01NX3BubCwgb3ZlcmFsbF9hdmVyYWdlX0luZm9ybWVkX3BubCwgb3ZlcmFsbF9hdmVyYWdlX05vaXN5SW5mb3JtZWQxX3BubCwgb3ZlcmFsbF9hdmVyYWdlX05vaXN5SW5mb3JtZWQyX3BubCwgb3ZlcmFsbF9hdmVyYWdlX05vaXN5SW5mb3JtZWQzX3BubCwgb3ZlcmFsbF9hdmVyYWdlX05vaXN5SW5mb3JtZWQ0X3BubCwgb3ZlcmFsbF9hdmVyYWdlX05vaXN5SW5mb3JtZWQ1X3BubCkpLCBtYXgoYyhvdmVyYWxsX2F2ZXJhZ2VfTU1fcG5sLCBvdmVyYWxsX2F2ZXJhZ2VfSW5mb3JtZWRfcG5sLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3lJbmZvcm1lZDFfcG5sLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3lJbmZvcm1lZDJfcG5sLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3lJbmZvcm1lZDNfcG5sLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3lJbmZvcm1lZDRfcG5sLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3lJbmZvcm1lZDVfcG5sKSkpKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfSW5mb3JtZWRfcG5sLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gInJlZCIpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9Ob2lzeUluZm9ybWVkMV9wbmwsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAiZ3JlZW4iKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfTm9pc3lJbmZvcm1lZDJfcG5sLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gInllbGxvdyIpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9Ob2lzeUluZm9ybWVkM19wbmwsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAiYmx1ZSIpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9Ob2lzeUluZm9ybWVkNF9wbmwsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAicHVycGxlIikKbGluZXMob3ZlcmFsbF9hdmVyYWdlX05vaXN5SW5mb3JtZWQ1X3BubCwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJvcmFuZ2UiKQoKIyBBZGQgbGVnZW5kCmxlZ2VuZCgiYm90dG9tbGVmdCIsIGxlZ2VuZCA9IGMoIk1hcmtldCBNYWtlciIsICJJbmZvcm1lZCIsICJOb2lzeSBJbmZvcm1lZCAxIiwgIk5vaXN5IEluZm9ybWVkIDIiLCAiTm9pc3kgSW5mb3JtZWQgMyIsICJOb2lzeSBJbmZvcm1lZCA0IiwgIk5vaXN5IEluZm9ybWVkIDUiKSwgY29sID0gYygiYmxhY2siLCAicmVkIiwgImdyZWVuIiwgInllbGxvdyIsICJibHVlIiwgInB1cnBsZSIsICJvcmFuZ2UiKSwgbHR5ID0gMSwgY2V4ID0gMC44KQpgYGAKCmBgYHtyfQojIEluaXRpYWxpemUgbWF0cmljZXMgdG8gc3RvcmUgYXZlcmFnZXMgZm9yIGVhY2ggcG9zaXRpb24KYXZlcmFnZV9NTV9wb3MgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfSW5mb3JtZWRfcG9zIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX05vaXN5SW5mb3JtZWQxX3BvcyA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKYXZlcmFnZV9Ob2lzeUluZm9ybWVkMl9wb3MgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfTm9pc3lJbmZvcm1lZDNfcG9zIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX05vaXN5SW5mb3JtZWQ0X3BvcyA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKYXZlcmFnZV9Ob2lzeUluZm9ybWVkNV9wb3MgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCgojIExvb3AgdGhyb3VnaCBlYWNoIHNpbXVsYXRpb24gKG4pCmZvciAobiBpbiAxOjEwKSB7CgogIE1NX3Bvc19zZXQ3IDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c183W24sIDddKSksICIsICIpCgogIEluZm9ybWVkX3Bvc19zZXQ3IDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c183W24sIDldKSksICIsICIpCiAgCiAgTm9pc3lJbmZvcm1lZDFfcG9zX3NldDcgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzdbbiwgMTFdKSksICIsICIpCiAgCiAgTm9pc3lJbmZvcm1lZDJfcG9zX3NldDcgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzdbbiwgMTNdKSksICIsICIpCiAgCiAgTm9pc3lJbmZvcm1lZDNfcG9zX3NldDcgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzdbbiwgMTVdKSksICIsICIpCiAgCiAgTm9pc3lJbmZvcm1lZDRfcG9zX3NldDcgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzdbbiwgMTddKSksICIsICIpCiAgCiAgTm9pc3lJbmZvcm1lZDVfcG9zX3NldDcgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzdbbiwgMTldKSksICIsICIpCiAgCiAgIyBMb29wIHRocm91Z2ggZWFjaCBwb3NpdGlvbiAoaSkKICBmb3IgKGkgaW4gMToxMDApIHsKICAgICMgRXh0cmFjdCBUcnVlIGFuZCBFeHBlY3RlZCB2YWx1ZXMgZm9yIHRoZSBpLXRoIHBvc2l0aW9uCiAgICBNTV9wb3MgPC0gc2FwcGx5KE1NX3Bvc19zZXQ3LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgSW5mb3JtZWRfcG9zIDwtIHNhcHBseShJbmZvcm1lZF9wb3Nfc2V0NywgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIE5vaXN5SW5mb3JtZWQxX3BvcyA8LSBzYXBwbHkoTm9pc3lJbmZvcm1lZDFfcG9zX3NldDcsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICBOb2lzeUluZm9ybWVkMl9wb3MgPC0gc2FwcGx5KE5vaXN5SW5mb3JtZWQyX3Bvc19zZXQ3LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgTm9pc3lJbmZvcm1lZDNfcG9zIDwtIHNhcHBseShOb2lzeUluZm9ybWVkM19wb3Nfc2V0NywgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIE5vaXN5SW5mb3JtZWQ0X3BvcyA8LSBzYXBwbHkoTm9pc3lJbmZvcm1lZDRfcG9zX3NldDcsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICBOb2lzeUluZm9ybWVkNV9wb3MgPC0gc2FwcGx5KE5vaXN5SW5mb3JtZWQ1X3Bvc19zZXQ3LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgCiAgICAjIENhbGN1bGF0ZSB0aGUgYXZlcmFnZSBvZiBUcnVlIGFuZCBFeHBlY3RlZCB2YWx1ZXMgZm9yIHRoZSBpLXRoIHBvc2l0aW9uCiAgICBhdmVyYWdlX01NX3Bvc1tpLCBuXSA8LSBtZWFuKE1NX3BvcywgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9JbmZvcm1lZF9wb3NbaSwgbl0gPC0gbWVhbihJbmZvcm1lZF9wb3MsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfTm9pc3lJbmZvcm1lZDFfcG9zW2ksIG5dIDwtIG1lYW4oTm9pc3lJbmZvcm1lZDFfcG9zLCBuYS5ybSA9IFRSVUUpCiAgICBhdmVyYWdlX05vaXN5SW5mb3JtZWQyX3Bvc1tpLCBuXSA8LSBtZWFuKE5vaXN5SW5mb3JtZWQyX3BvcywgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9Ob2lzeUluZm9ybWVkM19wb3NbaSwgbl0gPC0gbWVhbihOb2lzeUluZm9ybWVkM19wb3MsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfTm9pc3lJbmZvcm1lZDRfcG9zW2ksIG5dIDwtIG1lYW4oTm9pc3lJbmZvcm1lZDRfcG9zLCBuYS5ybSA9IFRSVUUpCiAgICBhdmVyYWdlX05vaXN5SW5mb3JtZWQ1X3Bvc1tpLCBuXSA8LSBtZWFuKE5vaXN5SW5mb3JtZWQ1X3BvcywgbmEucm0gPSBUUlVFKQogIH0KfQoKIyBDYWxjdWxhdGUgdGhlIG92ZXJhbGwgYXZlcmFnZSBmb3IgZWFjaCBwb3NpdGlvbiBhY3Jvc3MgYWxsIHNpbXVsYXRpb25zCm92ZXJhbGxfYXZlcmFnZV9NTV9wb3MgPC0gcm93TWVhbnMoYXZlcmFnZV9NTV9wb3MsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX0luZm9ybWVkX3BvcyA8LSByb3dNZWFucyhhdmVyYWdlX0luZm9ybWVkX3BvcywgbmEucm0gPSBUUlVFKQpvdmVyYWxsX2F2ZXJhZ2VfTm9pc3lJbmZvcm1lZDFfcG9zIDwtIHJvd01lYW5zKGF2ZXJhZ2VfTm9pc3lJbmZvcm1lZDFfcG9zLCBuYS5ybSA9IFRSVUUpCm92ZXJhbGxfYXZlcmFnZV9Ob2lzeUluZm9ybWVkMl9wb3MgPC0gcm93TWVhbnMoYXZlcmFnZV9Ob2lzeUluZm9ybWVkMl9wb3MsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX05vaXN5SW5mb3JtZWQzX3BvcyA8LSByb3dNZWFucyhhdmVyYWdlX05vaXN5SW5mb3JtZWQzX3BvcywgbmEucm0gPSBUUlVFKQpvdmVyYWxsX2F2ZXJhZ2VfTm9pc3lJbmZvcm1lZDRfcG9zIDwtIHJvd01lYW5zKGF2ZXJhZ2VfTm9pc3lJbmZvcm1lZDRfcG9zLCBuYS5ybSA9IFRSVUUpCm92ZXJhbGxfYXZlcmFnZV9Ob2lzeUluZm9ybWVkNV9wb3MgPC0gcm93TWVhbnMoYXZlcmFnZV9Ob2lzeUluZm9ybWVkNV9wb3MsIG5hLnJtID0gVFJVRSkKCiMgUGxvdCB0aGUgb3ZlcmFsbCBhdmVyYWdlcwpwbG90KG92ZXJhbGxfYXZlcmFnZV9NTV9wb3MsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAiYmxhY2siLCBtYWluID0gIk92ZXJhbGwgQXZlcmFnZSBQb3NpdGlvbiIsIHhsYWIgPSAiUG9zaXRpb24gaW4gTGlzdCIsIHlsYWIgPSAiVmFsdWUiLCB5bGltID0gYyhtaW4oYyhvdmVyYWxsX2F2ZXJhZ2VfTU1fcG9zLCBvdmVyYWxsX2F2ZXJhZ2VfSW5mb3JtZWRfcG9zLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3lJbmZvcm1lZDFfcG9zLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3lJbmZvcm1lZDJfcG9zLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3lJbmZvcm1lZDNfcG9zLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3lJbmZvcm1lZDRfcG9zLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3lJbmZvcm1lZDVfcG9zKSksIG1heChjKG92ZXJhbGxfYXZlcmFnZV9NTV9wb3MsIG92ZXJhbGxfYXZlcmFnZV9JbmZvcm1lZF9wb3MsIG92ZXJhbGxfYXZlcmFnZV9Ob2lzeUluZm9ybWVkMV9wb3MsIG92ZXJhbGxfYXZlcmFnZV9Ob2lzeUluZm9ybWVkMl9wb3MsIG92ZXJhbGxfYXZlcmFnZV9Ob2lzeUluZm9ybWVkM19wb3MsIG92ZXJhbGxfYXZlcmFnZV9Ob2lzeUluZm9ybWVkNF9wb3MsIG92ZXJhbGxfYXZlcmFnZV9Ob2lzeUluZm9ybWVkNV9wb3MpKSkpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9JbmZvcm1lZF9wb3MsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAicmVkIikKbGluZXMob3ZlcmFsbF9hdmVyYWdlX05vaXN5SW5mb3JtZWQxX3BvcywgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJncmVlbiIpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9Ob2lzeUluZm9ybWVkMl9wb3MsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAieWVsbG93IikKbGluZXMob3ZlcmFsbF9hdmVyYWdlX05vaXN5SW5mb3JtZWQzX3BvcywgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJibHVlIikKbGluZXMob3ZlcmFsbF9hdmVyYWdlX05vaXN5SW5mb3JtZWQ0X3BvcywgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJwdXJwbGUiKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfTm9pc3lJbmZvcm1lZDVfcG9zLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gIm9yYW5nZSIpCgojIEFkZCBsZWdlbmQKbGVnZW5kKCJib3R0b21sZWZ0IiwgbGVnZW5kID0gYygiTWFya2V0IE1ha2VyIiwgIkluZm9ybWVkIiwgIk5vaXN5IEluZm9ybWVkIDEiLCAiTm9pc3kgSW5mb3JtZWQgMiIsICJOb2lzeSBJbmZvcm1lZCAzIiwgIk5vaXN5IEluZm9ybWVkIDQiLCAiTm9pc3kgSW5mb3JtZWQgNSIpLCBjb2wgPSBjKCJibGFjayIsICJyZWQiLCAiZ3JlZW4iLCAieWVsbG93IiwgImJsdWUiLCAicHVycGxlIiwgIm9yYW5nZSIpLCBsdHkgPSAxLCBjZXggPSAwLjgpCmBgYAoKCgojIyBzZXQ4ICgxIGluZm9ybWVkICsgMiBub2lzeSBpbmZvcm1lZCArIDMgbm9pc3kpCgpgYGB7cn0KIyBJbml0aWFsaXplIG1hdHJpY2VzIHRvIHN0b3JlIGF2ZXJhZ2VzIGZvciBlYWNoIHBvc2l0aW9uCmF2ZXJhZ2VfdHJ1ZSA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKYXZlcmFnZV9leHBlY3RlZCA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKCiMgTG9vcCB0aHJvdWdoIGVhY2ggc2ltdWxhdGlvbiAobikKZm9yIChuIGluIDE6MTApIHsKICAjIEV4dHJhY3QgVHJ1ZSB2YWx1ZXMgZnJvbSB0aGUgYWdncmVnYXRlZF9yZXN1bHRzXzQgZGF0YWZyYW1lCiAgVHJ1ZVZhbHVlc19zZXQ4IDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c184W24sIDJdKSksICIsICIpCiAgCiAgIyBFeHRyYWN0IEV4cGVjdGVkIHZhbHVlcyBmcm9tIHRoZSBhZ2dyZWdhdGVkX3Jlc3VsdHNfNCBkYXRhZnJhbWUKICBFeHBlY3RlZFZhbHVlc19zZXQ4IDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c184W24sIDNdKSksICIsICIpCiAgCiAgIyBMb29wIHRocm91Z2ggZWFjaCBwb3NpdGlvbiAoaSkKICBmb3IgKGkgaW4gMToxMDApIHsKICAgICMgRXh0cmFjdCBUcnVlIGFuZCBFeHBlY3RlZCB2YWx1ZXMgZm9yIHRoZSBpLXRoIHBvc2l0aW9uCiAgICBUcnVlX3ZhbHVlcyA8LSBzYXBwbHkoVHJ1ZVZhbHVlc19zZXQ4LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgRXhwZWN0ZWRfdmFsdWVzIDwtIHNhcHBseShFeHBlY3RlZFZhbHVlc19zZXQ4LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgCiAgICAjIENhbGN1bGF0ZSB0aGUgYXZlcmFnZSBvZiBUcnVlIGFuZCBFeHBlY3RlZCB2YWx1ZXMgZm9yIHRoZSBpLXRoIHBvc2l0aW9uCiAgICBhdmVyYWdlX3RydWVbaSwgbl0gPC0gbWVhbihUcnVlX3ZhbHVlcywgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9leHBlY3RlZFtpLCBuXSA8LSBtZWFuKEV4cGVjdGVkX3ZhbHVlcywgbmEucm0gPSBUUlVFKQogIH0KfQoKIyBDYWxjdWxhdGUgdGhlIG92ZXJhbGwgYXZlcmFnZSBmb3IgZWFjaCBwb3NpdGlvbiBhY3Jvc3MgYWxsIHNpbXVsYXRpb25zCm92ZXJhbGxfYXZlcmFnZV90cnVlIDwtIHJvd01lYW5zKGF2ZXJhZ2VfdHJ1ZSwgbmEucm0gPSBUUlVFKQpvdmVyYWxsX2F2ZXJhZ2VfZXhwZWN0ZWQgPC0gcm93TWVhbnMoYXZlcmFnZV9leHBlY3RlZCwgbmEucm0gPSBUUlVFKQoKIyBQbG90IHRoZSBvdmVyYWxsIGF2ZXJhZ2VzCnBsb3Qob3ZlcmFsbF9hdmVyYWdlX3RydWUsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAiYmx1ZSIsIG1haW4gPSAiT3ZlcmFsbCBBdmVyYWdlIG9mIFRydWUgdnMgRXhwZWN0ZWQgVmFsdWVzIiwgeGxhYiA9ICJQb3NpdGlvbiBpbiBMaXN0IiwgeWxhYiA9ICJWYWx1ZSIsIHlsaW0gPSBjKG1pbihjKG92ZXJhbGxfYXZlcmFnZV90cnVlLCBvdmVyYWxsX2F2ZXJhZ2VfZXhwZWN0ZWQpKSwgbWF4KGMob3ZlcmFsbF9hdmVyYWdlX3RydWUsIG92ZXJhbGxfYXZlcmFnZV9leHBlY3RlZCkpKSkKbGluZXMob3ZlcmFsbF9hdmVyYWdlX2V4cGVjdGVkLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gInJlZCIpCmxlZ2VuZCgidG9wcmlnaHQiLCBsZWdlbmQgPSBjKCJUcnVlIFZhbHVlcyIsICJFeHBlY3RlZCBWYWx1ZXMiKSwgY29sID0gYygiYmx1ZSIsICJyZWQiKSwgbHR5ID0gMSwgY2V4ID0gMC44KQpgYGAKCgoKYGBge3J9CiMgSW5pdGlhbGl6ZSBtYXRyaWNlcyB0byBzdG9yZSBhdmVyYWdlcyBmb3IgZWFjaCBwb3NpdGlvbgphdmVyYWdlX2JpZCA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKYXZlcmFnZV9hc2sgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCgojIExvb3AgdGhyb3VnaCBlYWNoIHNpbXVsYXRpb24gKG4pCmZvciAobiBpbiAxOjEwKSB7CiAgIyBFeHRyYWN0IFRydWUgdmFsdWVzIGZyb20gdGhlIGFnZ3JlZ2F0ZWRfcmVzdWx0c180IGRhdGFmcmFtZQogIEJpZHNfc2V0OCA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfOFtuLCA0XSkpLCAiLCAiKQogIAogICMgRXh0cmFjdCBFeHBlY3RlZCB2YWx1ZXMgZnJvbSB0aGUgYWdncmVnYXRlZF9yZXN1bHRzXzQgZGF0YWZyYW1lCiAgQXNrc19zZXQ4IDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c184W24sIDVdKSksICIsICIpCiAgCiAgIyBMb29wIHRocm91Z2ggZWFjaCBwb3NpdGlvbiAoaSkKICBmb3IgKGkgaW4gMToxMDApIHsKICAgICMgRXh0cmFjdCBUcnVlIGFuZCBFeHBlY3RlZCB2YWx1ZXMgZm9yIHRoZSBpLXRoIHBvc2l0aW9uCiAgICBCaWRzIDwtIHNhcHBseShCaWRzX3NldDgsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICBBc2tzIDwtIHNhcHBseShBc2tzX3NldDgsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICAKICAgICMgQ2FsY3VsYXRlIHRoZSBhdmVyYWdlIG9mIFRydWUgYW5kIEV4cGVjdGVkIHZhbHVlcyBmb3IgdGhlIGktdGggcG9zaXRpb24KICAgIGF2ZXJhZ2VfYmlkW2ksIG5dIDwtIG1lYW4oQmlkcywgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9hc2tbaSwgbl0gPC0gbWVhbihBc2tzLCBuYS5ybSA9IFRSVUUpCiAgfQp9CgojIENhbGN1bGF0ZSB0aGUgb3ZlcmFsbCBhdmVyYWdlIGZvciBlYWNoIHBvc2l0aW9uIGFjcm9zcyBhbGwgc2ltdWxhdGlvbnMKb3ZlcmFsbF9hdmVyYWdlX2JpZCA8LSByb3dNZWFucyhhdmVyYWdlX2JpZCwgbmEucm0gPSBUUlVFKQpvdmVyYWxsX2F2ZXJhZ2VfYXNrIDwtIHJvd01lYW5zKGF2ZXJhZ2VfYXNrLCBuYS5ybSA9IFRSVUUpCgojIFBsb3QgdGhlIG92ZXJhbGwgYXZlcmFnZXMKcGxvdChvdmVyYWxsX2F2ZXJhZ2VfYmlkLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gImJsdWUiLCBtYWluID0gIk92ZXJhbGwgQXZlcmFnZSBvZiBCaWRzIHZzIEFza3MiLCB4bGFiID0gIlBvc2l0aW9uIGluIExpc3QiLCB5bGFiID0gIlZhbHVlIiwgeWxpbSA9IGMobWluKGMob3ZlcmFsbF9hdmVyYWdlX2JpZCwgb3ZlcmFsbF9hdmVyYWdlX2FzaykpLCBtYXgoYyhvdmVyYWxsX2F2ZXJhZ2VfYmlkLCBvdmVyYWxsX2F2ZXJhZ2VfYXNrKSkpKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfYXNrLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gInJlZCIpCmxlZ2VuZCgidG9wcmlnaHQiLCBsZWdlbmQgPSBjKCJCaWRzIiwgIkFza3MiKSwgY29sID0gYygiYmx1ZSIsICJyZWQiKSwgbHR5ID0gMSwgY2V4ID0gMC44KQpgYGAKCmBgYHtyfQojIEluaXRpYWxpemUgbWF0cmljZXMgdG8gc3RvcmUgYXZlcmFnZXMgZm9yIGVhY2ggcG9zaXRpb24KYXZlcmFnZV9iaWQgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfYXNrIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQoKIyBMb29wIHRocm91Z2ggZWFjaCBzaW11bGF0aW9uIChuKQpmb3IgKG4gaW4gMToxMCkgewogICMgRXh0cmFjdCBUcnVlIHZhbHVlcyBmcm9tIHRoZSBhZ2dyZWdhdGVkX3Jlc3VsdHNfNCBkYXRhZnJhbWUKICBCaWRzX3NldDggPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzhbbiwgNF0pKSwgIiwgIikKICAKICAjIEV4dHJhY3QgRXhwZWN0ZWQgdmFsdWVzIGZyb20gdGhlIGFnZ3JlZ2F0ZWRfcmVzdWx0c180IGRhdGFmcmFtZQogIEFza3Nfc2V0OCA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfOFtuLCA1XSkpLCAiLCAiKQogIAogICMgTG9vcCB0aHJvdWdoIGVhY2ggcG9zaXRpb24gKGkpCiAgZm9yIChpIGluIDE6MTAwKSB7CiAgICAjIEV4dHJhY3QgVHJ1ZSBhbmQgRXhwZWN0ZWQgdmFsdWVzIGZvciB0aGUgaS10aCBwb3NpdGlvbgogICAgQmlkcyA8LSBzYXBwbHkoQmlkc19zZXQ4LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgQXNrcyA8LSBzYXBwbHkoQXNrc19zZXQ4LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgCiAgICAjIENhbGN1bGF0ZSB0aGUgYXZlcmFnZSBvZiBUcnVlIGFuZCBFeHBlY3RlZCB2YWx1ZXMgZm9yIHRoZSBpLXRoIHBvc2l0aW9uCiAgICBhdmVyYWdlX2JpZFtpLCBuXSA8LSBtZWFuKEJpZHMsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfYXNrW2ksIG5dIDwtIG1lYW4oQXNrcywgbmEucm0gPSBUUlVFKQogIH0KfQoKIyBDYWxjdWxhdGUgdGhlIG92ZXJhbGwgYXZlcmFnZSBmb3IgZWFjaCBwb3NpdGlvbiBhY3Jvc3MgYWxsIHNpbXVsYXRpb25zCm92ZXJhbGxfYXZlcmFnZV9iaWQgPC0gcm93TWVhbnMoYXZlcmFnZV9iaWQsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX2FzayA8LSByb3dNZWFucyhhdmVyYWdlX2FzaywgbmEucm0gPSBUUlVFKQoKIyMgVHJ1ZSBWYWx1ZQojIEluaXRpYWxpemUgbWF0cmljZXMgdG8gc3RvcmUgYXZlcmFnZXMgZm9yIGVhY2ggcG9zaXRpb24KYXZlcmFnZV90cnVlIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX2V4cGVjdGVkIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQoKIyBMb29wIHRocm91Z2ggZWFjaCBzaW11bGF0aW9uIChuKQpmb3IgKG4gaW4gMToxMCkgewogICMgRXh0cmFjdCBUcnVlIHZhbHVlcyBmcm9tIHRoZSBhZ2dyZWdhdGVkX3Jlc3VsdHNfNCBkYXRhZnJhbWUKICBUcnVlVmFsdWVzX3NldDggPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzhbbiwgMl0pKSwgIiwgIikKICAKICAjIEV4dHJhY3QgRXhwZWN0ZWQgdmFsdWVzIGZyb20gdGhlIGFnZ3JlZ2F0ZWRfcmVzdWx0c180IGRhdGFmcmFtZQogIEV4cGVjdGVkVmFsdWVzX3NldDggPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzhbbiwgM10pKSwgIiwgIikKICAKICAjIExvb3AgdGhyb3VnaCBlYWNoIHBvc2l0aW9uIChpKQogIGZvciAoaSBpbiAxOjEwMCkgewogICAgIyBFeHRyYWN0IFRydWUgYW5kIEV4cGVjdGVkIHZhbHVlcyBmb3IgdGhlIGktdGggcG9zaXRpb24KICAgIFRydWVfdmFsdWVzIDwtIHNhcHBseShUcnVlVmFsdWVzX3NldDgsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICBFeHBlY3RlZF92YWx1ZXMgPC0gc2FwcGx5KEV4cGVjdGVkVmFsdWVzX3NldDgsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICAKICAgICMgQ2FsY3VsYXRlIHRoZSBhdmVyYWdlIG9mIFRydWUgYW5kIEV4cGVjdGVkIHZhbHVlcyBmb3IgdGhlIGktdGggcG9zaXRpb24KICAgIGF2ZXJhZ2VfdHJ1ZVtpLCBuXSA8LSBtZWFuKFRydWVfdmFsdWVzLCBuYS5ybSA9IFRSVUUpCiAgICBhdmVyYWdlX2V4cGVjdGVkW2ksIG5dIDwtIG1lYW4oRXhwZWN0ZWRfdmFsdWVzLCBuYS5ybSA9IFRSVUUpCiAgfQp9CgojIENhbGN1bGF0ZSB0aGUgb3ZlcmFsbCBhdmVyYWdlIGZvciBlYWNoIHBvc2l0aW9uIGFjcm9zcyBhbGwgc2ltdWxhdGlvbnMKb3ZlcmFsbF9hdmVyYWdlX3RydWUgPC0gcm93TWVhbnMoYXZlcmFnZV90cnVlLCBuYS5ybSA9IFRSVUUpCm92ZXJhbGxfYXZlcmFnZV9leHBlY3RlZCA8LSByb3dNZWFucyhhdmVyYWdlX2V4cGVjdGVkLCBuYS5ybSA9IFRSVUUpCgojIFBsb3QgdGhlIG92ZXJhbGwgYXZlcmFnZXMKI3Bsb3Qob3ZlcmFsbF9hdmVyYWdlX3RydWUsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAiYmx1ZSIsIG1haW4gPSAiT3ZlcmFsbCBBdmVyYWdlIG9mIFRydWUgdnMgRXhwZWN0ZWQgVmFsdWVzIiwgeGxhYiA9ICJQb3NpdGlvbiBpbiBMaXN0IiwgeWxhYiA9ICJWYWx1ZSIsIHlsaW0gPSBjKG1pbihjKG92ZXJhbGxfYXZlcmFnZV90cnVlLCBvdmVyYWxsX2F2ZXJhZ2VfZXhwZWN0ZWQpKSwgbWF4KGMob3ZlcmFsbF9hdmVyYWdlX3RydWUsIG92ZXJhbGxfYXZlcmFnZV9leHBlY3RlZCkpKSkKI2xpbmVzKG92ZXJhbGxfYXZlcmFnZV9leHBlY3RlZCwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJyZWQiKQojbGVnZW5kKCJ0b3ByaWdodCIsIGxlZ2VuZCA9IGMoIlRydWUgVmFsdWVzIiwgIkV4cGVjdGVkIFZhbHVlcyIpLCBjb2wgPSBjKCJibHVlIiwgInJlZCIpLCBsdHkgPSAxLCBjZXggPSAwLjgpCgojIFBsb3QgdGhlIG92ZXJhbGwgYXZlcmFnZXMKcGxvdChvdmVyYWxsX2F2ZXJhZ2VfYmlkLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gImJsdWUiLCBtYWluID0gIk92ZXJhbGwgQXZlcmFnZSBvZiBCaWRzIHZzIEFza3MgJiBUcnVlIHZzIEV4cGVjdGVkIFZhbHVlcyIsIHhsYWIgPSAiUG9zaXRpb24gaW4gTGlzdCIsIHlsYWIgPSAiVmFsdWUiLCB5bGltID0gYyhtaW4oYyhvdmVyYWxsX2F2ZXJhZ2VfYmlkLCBvdmVyYWxsX2F2ZXJhZ2VfYXNrLCBvdmVyYWxsX2F2ZXJhZ2VfdHJ1ZSwgb3ZlcmFsbF9hdmVyYWdlX2V4cGVjdGVkKSksIG1heChjKG92ZXJhbGxfYXZlcmFnZV9iaWQsIG92ZXJhbGxfYXZlcmFnZV9hc2ssIG92ZXJhbGxfYXZlcmFnZV90cnVlLCBvdmVyYWxsX2F2ZXJhZ2VfZXhwZWN0ZWQpKSkpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9hc2ssIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAicmVkIikKbGluZXMob3ZlcmFsbF9hdmVyYWdlX3RydWUsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAiZ3JlZW4iKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfZXhwZWN0ZWQsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAicHVycGxlIikKbGVnZW5kKCJib3R0b21sZWZ0IiwgbGVnZW5kID0gYygiQmlkcyIsICJBc2tzIiwgIlRydWUgVmFsdWUiLCAiRXhwZWN0ZWQgVmFsdWUiKSwgY29sID0gYygiYmx1ZSIsICJyZWQiLCAiZ3JlZW4iLCAicHVycGxlIiksIGx0eSA9IDEsIGNleCA9IDAuOCkKYGBgCgoKCmBgYHtyfQojIEluaXRpYWxpemUgbWF0cmljZXMgdG8gc3RvcmUgYXZlcmFnZXMgZm9yIGVhY2ggcG9zaXRpb24KYXZlcmFnZV9NTV9wbmwgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfSW5mb3JtZWRfcG5sIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX05vaXN5SW5mb3JtZWQxX3BubCA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKYXZlcmFnZV9Ob2lzeUluZm9ybWVkMl9wbmwgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfTm9pc3kxX3BubCA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKYXZlcmFnZV9Ob2lzeTJfcG5sIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX05vaXN5M19wbmwgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCgojIExvb3AgdGhyb3VnaCBlYWNoIHNpbXVsYXRpb24gKG4pCmZvciAobiBpbiAxOjEwKSB7CgogIE1NX3BubF9zZXQ4IDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c184W24sIDZdKSksICIsICIpCgogIEluZm9ybWVkX3BubF9zZXQ4IDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c184W24sIDhdKSksICIsICIpCiAgCiAgTm9pc3lJbmZvcm1lZDFfcG5sX3NldDggPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzhbbiwgMTBdKSksICIsICIpCiAgCiAgTm9pc3lJbmZvcm1lZDJfcG5sX3NldDggPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzhbbiwgMTJdKSksICIsICIpCiAgCiAgTm9pc3kxX3BubF9zZXQ4IDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c184W24sIDE0XSkpLCAiLCAiKQogIAogIE5vaXN5Ml9wbmxfc2V0OCA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfOFtuLCAxNl0pKSwgIiwgIikKICAKICBOb2lzeTNfcG5sX3NldDggPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzhbbiwgMThdKSksICIsICIpCiAgCiAgIyBMb29wIHRocm91Z2ggZWFjaCBwb3NpdGlvbiAoaSkKICBmb3IgKGkgaW4gMToxMDApIHsKICAgICMgRXh0cmFjdCBUcnVlIGFuZCBFeHBlY3RlZCB2YWx1ZXMgZm9yIHRoZSBpLXRoIHBvc2l0aW9uCiAgICBNTV9wbmwgPC0gc2FwcGx5KE1NX3BubF9zZXQ4LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgSW5mb3JtZWRfcG5sIDwtIHNhcHBseShJbmZvcm1lZF9wbmxfc2V0OCwgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIE5vaXN5SW5mb3JtZWQxX3BubCA8LSBzYXBwbHkoTm9pc3lJbmZvcm1lZDFfcG5sX3NldDgsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICBOb2lzeUluZm9ybWVkMl9wbmwgPC0gc2FwcGx5KE5vaXN5SW5mb3JtZWQyX3BubF9zZXQ4LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgTm9pc3kxX3BubCA8LSBzYXBwbHkoTm9pc3kxX3BubF9zZXQ4LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgTm9pc3kyX3BubCA8LSBzYXBwbHkoTm9pc3kyX3BubF9zZXQ4LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgTm9pc3kzX3BubCA8LSBzYXBwbHkoTm9pc3kzX3BubF9zZXQ4LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgCiAgICAjIENhbGN1bGF0ZSB0aGUgYXZlcmFnZSBvZiBUcnVlIGFuZCBFeHBlY3RlZCB2YWx1ZXMgZm9yIHRoZSBpLXRoIHBvc2l0aW9uCiAgICBhdmVyYWdlX01NX3BubFtpLCBuXSA8LSBtZWFuKE1NX3BubCwgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9JbmZvcm1lZF9wbmxbaSwgbl0gPC0gbWVhbihJbmZvcm1lZF9wbmwsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfTm9pc3lJbmZvcm1lZDFfcG5sW2ksIG5dIDwtIG1lYW4oTm9pc3lJbmZvcm1lZDFfcG5sLCBuYS5ybSA9IFRSVUUpCiAgICBhdmVyYWdlX05vaXN5SW5mb3JtZWQyX3BubFtpLCBuXSA8LSBtZWFuKE5vaXN5SW5mb3JtZWQyX3BubCwgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9Ob2lzeTFfcG5sW2ksIG5dIDwtIG1lYW4oTm9pc3kxX3BubCwgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9Ob2lzeTJfcG5sW2ksIG5dIDwtIG1lYW4oTm9pc3kyX3BubCwgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9Ob2lzeTNfcG5sW2ksIG5dIDwtIG1lYW4oTm9pc3kzX3BubCwgbmEucm0gPSBUUlVFKQogIH0KfQoKIyBDYWxjdWxhdGUgdGhlIG92ZXJhbGwgYXZlcmFnZSBmb3IgZWFjaCBwb3NpdGlvbiBhY3Jvc3MgYWxsIHNpbXVsYXRpb25zCm92ZXJhbGxfYXZlcmFnZV9NTV9wbmwgPC0gcm93TWVhbnMoYXZlcmFnZV9NTV9wbmwsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX0luZm9ybWVkX3BubCA8LSByb3dNZWFucyhhdmVyYWdlX0luZm9ybWVkX3BubCwgbmEucm0gPSBUUlVFKQpvdmVyYWxsX2F2ZXJhZ2VfTm9pc3lJbmZvcm1lZDFfcG5sIDwtIHJvd01lYW5zKGF2ZXJhZ2VfTm9pc3lJbmZvcm1lZDFfcG5sLCBuYS5ybSA9IFRSVUUpCm92ZXJhbGxfYXZlcmFnZV9Ob2lzeUluZm9ybWVkMl9wbmwgPC0gcm93TWVhbnMoYXZlcmFnZV9Ob2lzeUluZm9ybWVkMl9wbmwsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX05vaXN5MV9wbmwgPC0gcm93TWVhbnMoYXZlcmFnZV9Ob2lzeTFfcG5sLCBuYS5ybSA9IFRSVUUpCm92ZXJhbGxfYXZlcmFnZV9Ob2lzeTJfcG5sIDwtIHJvd01lYW5zKGF2ZXJhZ2VfTm9pc3kyX3BubCwgbmEucm0gPSBUUlVFKQpvdmVyYWxsX2F2ZXJhZ2VfTm9pc3kzX3BubCA8LSByb3dNZWFucyhhdmVyYWdlX05vaXN5M19wbmwsIG5hLnJtID0gVFJVRSkKCiMgUGxvdCB0aGUgb3ZlcmFsbCBhdmVyYWdlcwpwbG90KG92ZXJhbGxfYXZlcmFnZV9NTV9wbmwsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAiYmxhY2siLCBtYWluID0gIk92ZXJhbGwgQXZlcmFnZSBQTkwiLCB4bGFiID0gIlBvc2l0aW9uIGluIExpc3QiLCB5bGFiID0gIlZhbHVlIiwgeWxpbSA9IGMobWluKGMob3ZlcmFsbF9hdmVyYWdlX01NX3BubCwgb3ZlcmFsbF9hdmVyYWdlX0luZm9ybWVkX3BubCwgb3ZlcmFsbF9hdmVyYWdlX05vaXN5SW5mb3JtZWQxX3BubCwgb3ZlcmFsbF9hdmVyYWdlX05vaXN5SW5mb3JtZWQyX3BubCwgb3ZlcmFsbF9hdmVyYWdlX05vaXN5MV9wbmwsIG92ZXJhbGxfYXZlcmFnZV9Ob2lzeTJfcG5sLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3kzX3BubCkpLCBtYXgoYyhvdmVyYWxsX2F2ZXJhZ2VfTU1fcG5sLCBvdmVyYWxsX2F2ZXJhZ2VfSW5mb3JtZWRfcG5sLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3lJbmZvcm1lZDFfcG5sLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3lJbmZvcm1lZDJfcG5sLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3kxX3BubCwgb3ZlcmFsbF9hdmVyYWdlX05vaXN5Ml9wbmwsIG92ZXJhbGxfYXZlcmFnZV9Ob2lzeTNfcG5sKSkpKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfSW5mb3JtZWRfcG5sLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gInJlZCIpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9Ob2lzeUluZm9ybWVkMV9wbmwsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAiZ3JlZW4iKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfTm9pc3lJbmZvcm1lZDJfcG5sLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gInllbGxvdyIpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9Ob2lzeTFfcG5sLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gImJsdWUiKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfTm9pc3kyX3BubCwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJwdXJwbGUiKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfTm9pc3kzX3BubCwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJvcmFuZ2UiKQoKIyBBZGQgbGVnZW5kCmxlZ2VuZCgiYm90dG9tbGVmdCIsIGxlZ2VuZCA9IGMoIk1hcmtldCBNYWtlciIsICJJbmZvcm1lZCIsICJOb2lzeSBJbmZvcm1lZCAxIiwgIk5vaXN5IEluZm9ybWVkIDIiLCAiTm9pc3kgMyIsICJOb2lzeSA0IiwgIk5vaXN5IDUiKSwgY29sID0gYygiYmxhY2siLCAicmVkIiwgImdyZWVuIiwgInllbGxvdyIsICJibHVlIiwgInB1cnBsZSIsICJvcmFuZ2UiKSwgbHR5ID0gMSwgY2V4ID0gMC44KQpgYGAKCmBgYHtyfQojIEluaXRpYWxpemUgbWF0cmljZXMgdG8gc3RvcmUgYXZlcmFnZXMgZm9yIGVhY2ggcG9zaXRpb24KYXZlcmFnZV9NTV9wbmwgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfSW5mb3JtZWRfcG5sIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX05vaXN5SW5mb3JtZWQxX3BubCA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKYXZlcmFnZV9Ob2lzeUluZm9ybWVkMl9wbmwgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfTm9pc3kxX3BubCA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKYXZlcmFnZV9Ob2lzeTJfcG5sIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX05vaXN5M19wbmwgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCgojIExvb3AgdGhyb3VnaCBlYWNoIHNpbXVsYXRpb24gKG4pCmZvciAobiBpbiAxOjEwKSB7CgogIE1NX3Bvc19zZXQ4IDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c184W24sIDddKSksICIsICIpCgogIEluZm9ybWVkX3Bvc19zZXQ4IDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c184W24sIDldKSksICIsICIpCiAgCiAgTm9pc3lJbmZvcm1lZDFfcG9zX3NldDggPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzhbbiwgMTFdKSksICIsICIpCiAgCiAgTm9pc3lJbmZvcm1lZDJfcG9zX3NldDggPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzhbbiwgMTNdKSksICIsICIpCiAgCiAgTm9pc3kxX3Bvc19zZXQ4IDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c184W24sIDE1XSkpLCAiLCAiKQogIAogIE5vaXN5Ml9wb3Nfc2V0OCA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfOFtuLCAxN10pKSwgIiwgIikKICAKICBOb2lzeTNfcG9zX3NldDggPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzhbbiwgMTldKSksICIsICIpCiAgCiAgIyBMb29wIHRocm91Z2ggZWFjaCBwb3NpdGlvbiAoaSkKICBmb3IgKGkgaW4gMToxMDApIHsKICAgICMgRXh0cmFjdCBUcnVlIGFuZCBFeHBlY3RlZCB2YWx1ZXMgZm9yIHRoZSBpLXRoIHBvc2l0aW9uCiAgICBNTV9wb3MgPC0gc2FwcGx5KE1NX3Bvc19zZXQ4LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgSW5mb3JtZWRfcG9zIDwtIHNhcHBseShJbmZvcm1lZF9wb3Nfc2V0OCwgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIE5vaXN5SW5mb3JtZWQxX3BvcyA8LSBzYXBwbHkoTm9pc3lJbmZvcm1lZDFfcG9zX3NldDgsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICBOb2lzeUluZm9ybWVkMl9wb3MgPC0gc2FwcGx5KE5vaXN5SW5mb3JtZWQyX3Bvc19zZXQ4LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgTm9pc3kxX3BvcyA8LSBzYXBwbHkoTm9pc3kxX3Bvc19zZXQ4LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgTm9pc3kyX3BvcyA8LSBzYXBwbHkoTm9pc3kyX3Bvc19zZXQ4LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgTm9pc3kzX3BvcyA8LSBzYXBwbHkoTm9pc3kzX3Bvc19zZXQ4LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgCiAgICAjIENhbGN1bGF0ZSB0aGUgYXZlcmFnZSBvZiBUcnVlIGFuZCBFeHBlY3RlZCB2YWx1ZXMgZm9yIHRoZSBpLXRoIHBvc2l0aW9uCiAgICBhdmVyYWdlX01NX3Bvc1tpLCBuXSA8LSBtZWFuKE1NX3BvcywgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9JbmZvcm1lZF9wb3NbaSwgbl0gPC0gbWVhbihJbmZvcm1lZF9wb3MsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfTm9pc3lJbmZvcm1lZDFfcG9zW2ksIG5dIDwtIG1lYW4oTm9pc3lJbmZvcm1lZDFfcG9zLCBuYS5ybSA9IFRSVUUpCiAgICBhdmVyYWdlX05vaXN5SW5mb3JtZWQyX3Bvc1tpLCBuXSA8LSBtZWFuKE5vaXN5SW5mb3JtZWQyX3BvcywgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9Ob2lzeTFfcG9zW2ksIG5dIDwtIG1lYW4oTm9pc3kxX3BvcywgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9Ob2lzeTJfcG9zW2ksIG5dIDwtIG1lYW4oTm9pc3kyX3BvcywgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9Ob2lzeTNfcG9zW2ksIG5dIDwtIG1lYW4oTm9pc3kzX3BvcywgbmEucm0gPSBUUlVFKQogIH0KfQoKIyBDYWxjdWxhdGUgdGhlIG92ZXJhbGwgYXZlcmFnZSBmb3IgZWFjaCBwb3NpdGlvbiBhY3Jvc3MgYWxsIHNpbXVsYXRpb25zCm92ZXJhbGxfYXZlcmFnZV9NTV9wb3MgPC0gcm93TWVhbnMoYXZlcmFnZV9NTV9wb3MsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX0luZm9ybWVkX3BvcyA8LSByb3dNZWFucyhhdmVyYWdlX0luZm9ybWVkX3BvcywgbmEucm0gPSBUUlVFKQpvdmVyYWxsX2F2ZXJhZ2VfTm9pc3lJbmZvcm1lZDFfcG9zIDwtIHJvd01lYW5zKGF2ZXJhZ2VfTm9pc3lJbmZvcm1lZDFfcG9zLCBuYS5ybSA9IFRSVUUpCm92ZXJhbGxfYXZlcmFnZV9Ob2lzeUluZm9ybWVkMl9wb3MgPC0gcm93TWVhbnMoYXZlcmFnZV9Ob2lzeUluZm9ybWVkMl9wb3MsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX05vaXN5MV9wb3MgPC0gcm93TWVhbnMoYXZlcmFnZV9Ob2lzeTFfcG9zLCBuYS5ybSA9IFRSVUUpCm92ZXJhbGxfYXZlcmFnZV9Ob2lzeTJfcG9zIDwtIHJvd01lYW5zKGF2ZXJhZ2VfTm9pc3kyX3BvcywgbmEucm0gPSBUUlVFKQpvdmVyYWxsX2F2ZXJhZ2VfTm9pc3kzX3BvcyA8LSByb3dNZWFucyhhdmVyYWdlX05vaXN5M19wb3MsIG5hLnJtID0gVFJVRSkKCiMgUGxvdCB0aGUgb3ZlcmFsbCBhdmVyYWdlcwpwbG90KG92ZXJhbGxfYXZlcmFnZV9NTV9wb3MsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAiYmxhY2siLCBtYWluID0gIk92ZXJhbGwgQXZlcmFnZSBQb3NpdGlvbiIsIHhsYWIgPSAiUG9zaXRpb24gaW4gTGlzdCIsIHlsYWIgPSAiVmFsdWUiLCB5bGltID0gYyhtaW4oYyhvdmVyYWxsX2F2ZXJhZ2VfTU1fcG9zLCBvdmVyYWxsX2F2ZXJhZ2VfSW5mb3JtZWRfcG9zLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3lJbmZvcm1lZDFfcG9zLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3lJbmZvcm1lZDJfcG9zLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3kxX3Bvcywgb3ZlcmFsbF9hdmVyYWdlX05vaXN5Ml9wb3MsIG92ZXJhbGxfYXZlcmFnZV9Ob2lzeTNfcG9zKSksIG1heChjKG92ZXJhbGxfYXZlcmFnZV9NTV9wb3MsIG92ZXJhbGxfYXZlcmFnZV9JbmZvcm1lZF9wb3MsIG92ZXJhbGxfYXZlcmFnZV9Ob2lzeUluZm9ybWVkMV9wb3MsIG92ZXJhbGxfYXZlcmFnZV9Ob2lzeUluZm9ybWVkMl9wb3MsIG92ZXJhbGxfYXZlcmFnZV9Ob2lzeTFfcG9zLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3kyX3Bvcywgb3ZlcmFsbF9hdmVyYWdlX05vaXN5M19wb3MpKSkpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9JbmZvcm1lZF9wb3MsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAicmVkIikKbGluZXMob3ZlcmFsbF9hdmVyYWdlX05vaXN5SW5mb3JtZWQxX3BvcywgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJncmVlbiIpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9Ob2lzeUluZm9ybWVkMl9wb3MsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAieWVsbG93IikKbGluZXMob3ZlcmFsbF9hdmVyYWdlX05vaXN5MV9wb3MsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAiYmx1ZSIpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9Ob2lzeTJfcG9zLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gInB1cnBsZSIpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9Ob2lzeTNfcG9zLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gIm9yYW5nZSIpCgojIEFkZCBsZWdlbmQKbGVnZW5kKCJib3R0b21sZWZ0IiwgbGVnZW5kID0gYygiTWFya2V0IE1ha2VyIiwgIkluZm9ybWVkIiwgIk5vaXN5IEluZm9ybWVkIDEiLCAiTm9pc3kgSW5mb3JtZWQgMiIsICJOb2lzeSAzIiwgIk5vaXN5IDQiLCAiTm9pc3kgNSIpLCBjb2wgPSBjKCJibGFjayIsICJyZWQiLCAiZ3JlZW4iLCAieWVsbG93IiwgImJsdWUiLCAicHVycGxlIiwgIm9yYW5nZSIpLCBsdHkgPSAxLCBjZXggPSAwLjgpCmBgYAoKCiMjIHNldDkgKE1lYW4gUmV2ZXJzaW9uOiA2KQoKCmBgYHtyfQojIEluaXRpYWxpemUgbWF0cmljZXMgdG8gc3RvcmUgYXZlcmFnZXMgZm9yIGVhY2ggcG9zaXRpb24KYXZlcmFnZV90cnVlIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX2V4cGVjdGVkIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQoKIyBMb29wIHRocm91Z2ggZWFjaCBzaW11bGF0aW9uIChuKQpmb3IgKG4gaW4gMToxMCkgewogICMgRXh0cmFjdCBUcnVlIHZhbHVlcyBmcm9tIHRoZSBhZ2dyZWdhdGVkX3Jlc3VsdHNfNCBkYXRhZnJhbWUKICBUcnVlVmFsdWVzX3NldDkgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzlbbiwgMl0pKSwgIiwgIikKICAKICAjIEV4dHJhY3QgRXhwZWN0ZWQgdmFsdWVzIGZyb20gdGhlIGFnZ3JlZ2F0ZWRfcmVzdWx0c180IGRhdGFmcmFtZQogIEV4cGVjdGVkVmFsdWVzX3NldDkgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzlbbiwgM10pKSwgIiwgIikKICAKICAjIExvb3AgdGhyb3VnaCBlYWNoIHBvc2l0aW9uIChpKQogIGZvciAoaSBpbiAxOjEwMCkgewogICAgIyBFeHRyYWN0IFRydWUgYW5kIEV4cGVjdGVkIHZhbHVlcyBmb3IgdGhlIGktdGggcG9zaXRpb24KICAgIFRydWVfdmFsdWVzIDwtIHNhcHBseShUcnVlVmFsdWVzX3NldDksIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICBFeHBlY3RlZF92YWx1ZXMgPC0gc2FwcGx5KEV4cGVjdGVkVmFsdWVzX3NldDksIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICAKICAgICMgQ2FsY3VsYXRlIHRoZSBhdmVyYWdlIG9mIFRydWUgYW5kIEV4cGVjdGVkIHZhbHVlcyBmb3IgdGhlIGktdGggcG9zaXRpb24KICAgIGF2ZXJhZ2VfdHJ1ZVtpLCBuXSA8LSBtZWFuKFRydWVfdmFsdWVzLCBuYS5ybSA9IFRSVUUpCiAgICBhdmVyYWdlX2V4cGVjdGVkW2ksIG5dIDwtIG1lYW4oRXhwZWN0ZWRfdmFsdWVzLCBuYS5ybSA9IFRSVUUpCiAgfQp9CgojIENhbGN1bGF0ZSB0aGUgb3ZlcmFsbCBhdmVyYWdlIGZvciBlYWNoIHBvc2l0aW9uIGFjcm9zcyBhbGwgc2ltdWxhdGlvbnMKb3ZlcmFsbF9hdmVyYWdlX3RydWUgPC0gcm93TWVhbnMoYXZlcmFnZV90cnVlLCBuYS5ybSA9IFRSVUUpCm92ZXJhbGxfYXZlcmFnZV9leHBlY3RlZCA8LSByb3dNZWFucyhhdmVyYWdlX2V4cGVjdGVkLCBuYS5ybSA9IFRSVUUpCgojIFBsb3QgdGhlIG92ZXJhbGwgYXZlcmFnZXMKcGxvdChvdmVyYWxsX2F2ZXJhZ2VfdHJ1ZSwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJibHVlIiwgbWFpbiA9ICJPdmVyYWxsIEF2ZXJhZ2Ugb2YgVHJ1ZSB2cyBFeHBlY3RlZCBWYWx1ZXMiLCB4bGFiID0gIlBvc2l0aW9uIGluIExpc3QiLCB5bGFiID0gIlZhbHVlIiwgeWxpbSA9IGMobWluKGMob3ZlcmFsbF9hdmVyYWdlX3RydWUsIG92ZXJhbGxfYXZlcmFnZV9leHBlY3RlZCkpLCBtYXgoYyhvdmVyYWxsX2F2ZXJhZ2VfdHJ1ZSwgb3ZlcmFsbF9hdmVyYWdlX2V4cGVjdGVkKSkpKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfZXhwZWN0ZWQsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAicmVkIikKbGVnZW5kKCJ0b3ByaWdodCIsIGxlZ2VuZCA9IGMoIlRydWUgVmFsdWVzIiwgIkV4cGVjdGVkIFZhbHVlcyIpLCBjb2wgPSBjKCJibHVlIiwgInJlZCIpLCBsdHkgPSAxLCBjZXggPSAwLjgpCmBgYAoKYGBge3J9CiMgSW5pdGlhbGl6ZSBtYXRyaWNlcyB0byBzdG9yZSBhdmVyYWdlcyBmb3IgZWFjaCBwb3NpdGlvbgphdmVyYWdlX2JpZCA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKYXZlcmFnZV9hc2sgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCgojIExvb3AgdGhyb3VnaCBlYWNoIHNpbXVsYXRpb24gKG4pCmZvciAobiBpbiAxOjEwKSB7CiAgIyBFeHRyYWN0IFRydWUgdmFsdWVzIGZyb20gdGhlIGFnZ3JlZ2F0ZWRfcmVzdWx0c180IGRhdGFmcmFtZQogIEJpZHNfc2V0OSA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfOVtuLCA0XSkpLCAiLCAiKQogIAogICMgRXh0cmFjdCBFeHBlY3RlZCB2YWx1ZXMgZnJvbSB0aGUgYWdncmVnYXRlZF9yZXN1bHRzXzQgZGF0YWZyYW1lCiAgQXNrc19zZXQ5IDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c185W24sIDVdKSksICIsICIpCiAgCiAgIyBMb29wIHRocm91Z2ggZWFjaCBwb3NpdGlvbiAoaSkKICBmb3IgKGkgaW4gMToxMDApIHsKICAgICMgRXh0cmFjdCBUcnVlIGFuZCBFeHBlY3RlZCB2YWx1ZXMgZm9yIHRoZSBpLXRoIHBvc2l0aW9uCiAgICBCaWRzIDwtIHNhcHBseShCaWRzX3NldDksIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICBBc2tzIDwtIHNhcHBseShBc2tzX3NldDksIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICAKICAgICMgQ2FsY3VsYXRlIHRoZSBhdmVyYWdlIG9mIFRydWUgYW5kIEV4cGVjdGVkIHZhbHVlcyBmb3IgdGhlIGktdGggcG9zaXRpb24KICAgIGF2ZXJhZ2VfYmlkW2ksIG5dIDwtIG1lYW4oQmlkcywgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9hc2tbaSwgbl0gPC0gbWVhbihBc2tzLCBuYS5ybSA9IFRSVUUpCiAgfQp9CgojIENhbGN1bGF0ZSB0aGUgb3ZlcmFsbCBhdmVyYWdlIGZvciBlYWNoIHBvc2l0aW9uIGFjcm9zcyBhbGwgc2ltdWxhdGlvbnMKb3ZlcmFsbF9hdmVyYWdlX2JpZCA8LSByb3dNZWFucyhhdmVyYWdlX2JpZCwgbmEucm0gPSBUUlVFKQpvdmVyYWxsX2F2ZXJhZ2VfYXNrIDwtIHJvd01lYW5zKGF2ZXJhZ2VfYXNrLCBuYS5ybSA9IFRSVUUpCgojIFBsb3QgdGhlIG92ZXJhbGwgYXZlcmFnZXMKcGxvdChvdmVyYWxsX2F2ZXJhZ2VfYmlkLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gImJsdWUiLCBtYWluID0gIk92ZXJhbGwgQXZlcmFnZSBvZiBCaWRzIHZzIEFza3MiLCB4bGFiID0gIlBvc2l0aW9uIGluIExpc3QiLCB5bGFiID0gIlZhbHVlIiwgeWxpbSA9IGMobWluKGMob3ZlcmFsbF9hdmVyYWdlX2JpZCwgb3ZlcmFsbF9hdmVyYWdlX2FzaykpLCBtYXgoYyhvdmVyYWxsX2F2ZXJhZ2VfYmlkLCBvdmVyYWxsX2F2ZXJhZ2VfYXNrKSkpKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfYXNrLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gInJlZCIpCmxlZ2VuZCgidG9wcmlnaHQiLCBsZWdlbmQgPSBjKCJCaWRzIiwgIkFza3MiKSwgY29sID0gYygiYmx1ZSIsICJyZWQiKSwgbHR5ID0gMSwgY2V4ID0gMC44KQpgYGAKCmBgYHtyfQojIEluaXRpYWxpemUgbWF0cmljZXMgdG8gc3RvcmUgYXZlcmFnZXMgZm9yIGVhY2ggcG9zaXRpb24KYXZlcmFnZV9iaWQgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfYXNrIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQoKIyBMb29wIHRocm91Z2ggZWFjaCBzaW11bGF0aW9uIChuKQpmb3IgKG4gaW4gMToxMCkgewogICMgRXh0cmFjdCBUcnVlIHZhbHVlcyBmcm9tIHRoZSBhZ2dyZWdhdGVkX3Jlc3VsdHNfNCBkYXRhZnJhbWUKICBCaWRzX3NldDkgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzlbbiwgNF0pKSwgIiwgIikKICAKICAjIEV4dHJhY3QgRXhwZWN0ZWQgdmFsdWVzIGZyb20gdGhlIGFnZ3JlZ2F0ZWRfcmVzdWx0c180IGRhdGFmcmFtZQogIEFza3Nfc2V0OSA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfOVtuLCA1XSkpLCAiLCAiKQogIAogICMgTG9vcCB0aHJvdWdoIGVhY2ggcG9zaXRpb24gKGkpCiAgZm9yIChpIGluIDE6MTAwKSB7CiAgICAjIEV4dHJhY3QgVHJ1ZSBhbmQgRXhwZWN0ZWQgdmFsdWVzIGZvciB0aGUgaS10aCBwb3NpdGlvbgogICAgQmlkcyA8LSBzYXBwbHkoQmlkc19zZXQ5LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgQXNrcyA8LSBzYXBwbHkoQXNrc19zZXQ5LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgCiAgICAjIENhbGN1bGF0ZSB0aGUgYXZlcmFnZSBvZiBUcnVlIGFuZCBFeHBlY3RlZCB2YWx1ZXMgZm9yIHRoZSBpLXRoIHBvc2l0aW9uCiAgICBhdmVyYWdlX2JpZFtpLCBuXSA8LSBtZWFuKEJpZHMsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfYXNrW2ksIG5dIDwtIG1lYW4oQXNrcywgbmEucm0gPSBUUlVFKQogIH0KfQoKIyBDYWxjdWxhdGUgdGhlIG92ZXJhbGwgYXZlcmFnZSBmb3IgZWFjaCBwb3NpdGlvbiBhY3Jvc3MgYWxsIHNpbXVsYXRpb25zCm92ZXJhbGxfYXZlcmFnZV9iaWQgPC0gcm93TWVhbnMoYXZlcmFnZV9iaWQsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX2FzayA8LSByb3dNZWFucyhhdmVyYWdlX2FzaywgbmEucm0gPSBUUlVFKQoKIyMgVHJ1ZSBWYWx1ZQojIEluaXRpYWxpemUgbWF0cmljZXMgdG8gc3RvcmUgYXZlcmFnZXMgZm9yIGVhY2ggcG9zaXRpb24KYXZlcmFnZV90cnVlIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX2V4cGVjdGVkIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQoKIyBMb29wIHRocm91Z2ggZWFjaCBzaW11bGF0aW9uIChuKQpmb3IgKG4gaW4gMToxMCkgewogICMgRXh0cmFjdCBUcnVlIHZhbHVlcyBmcm9tIHRoZSBhZ2dyZWdhdGVkX3Jlc3VsdHNfNCBkYXRhZnJhbWUKICBUcnVlVmFsdWVzX3NldDkgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzlbbiwgMl0pKSwgIiwgIikKICAKICAjIEV4dHJhY3QgRXhwZWN0ZWQgdmFsdWVzIGZyb20gdGhlIGFnZ3JlZ2F0ZWRfcmVzdWx0c180IGRhdGFmcmFtZQogIEV4cGVjdGVkVmFsdWVzX3NldDkgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzlbbiwgM10pKSwgIiwgIikKICAKICAjIExvb3AgdGhyb3VnaCBlYWNoIHBvc2l0aW9uIChpKQogIGZvciAoaSBpbiAxOjEwMCkgewogICAgIyBFeHRyYWN0IFRydWUgYW5kIEV4cGVjdGVkIHZhbHVlcyBmb3IgdGhlIGktdGggcG9zaXRpb24KICAgIFRydWVfdmFsdWVzIDwtIHNhcHBseShUcnVlVmFsdWVzX3NldDksIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICBFeHBlY3RlZF92YWx1ZXMgPC0gc2FwcGx5KEV4cGVjdGVkVmFsdWVzX3NldDksIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICAKICAgICMgQ2FsY3VsYXRlIHRoZSBhdmVyYWdlIG9mIFRydWUgYW5kIEV4cGVjdGVkIHZhbHVlcyBmb3IgdGhlIGktdGggcG9zaXRpb24KICAgIGF2ZXJhZ2VfdHJ1ZVtpLCBuXSA8LSBtZWFuKFRydWVfdmFsdWVzLCBuYS5ybSA9IFRSVUUpCiAgICBhdmVyYWdlX2V4cGVjdGVkW2ksIG5dIDwtIG1lYW4oRXhwZWN0ZWRfdmFsdWVzLCBuYS5ybSA9IFRSVUUpCiAgfQp9CgojIENhbGN1bGF0ZSB0aGUgb3ZlcmFsbCBhdmVyYWdlIGZvciBlYWNoIHBvc2l0aW9uIGFjcm9zcyBhbGwgc2ltdWxhdGlvbnMKb3ZlcmFsbF9hdmVyYWdlX3RydWUgPC0gcm93TWVhbnMoYXZlcmFnZV90cnVlLCBuYS5ybSA9IFRSVUUpCm92ZXJhbGxfYXZlcmFnZV9leHBlY3RlZCA8LSByb3dNZWFucyhhdmVyYWdlX2V4cGVjdGVkLCBuYS5ybSA9IFRSVUUpCgojIFBsb3QgdGhlIG92ZXJhbGwgYXZlcmFnZXMKI3Bsb3Qob3ZlcmFsbF9hdmVyYWdlX3RydWUsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAiYmx1ZSIsIG1haW4gPSAiT3ZlcmFsbCBBdmVyYWdlIG9mIFRydWUgdnMgRXhwZWN0ZWQgVmFsdWVzIiwgeGxhYiA9ICJQb3NpdGlvbiBpbiBMaXN0IiwgeWxhYiA9ICJWYWx1ZSIsIHlsaW0gPSBjKG1pbihjKG92ZXJhbGxfYXZlcmFnZV90cnVlLCBvdmVyYWxsX2F2ZXJhZ2VfZXhwZWN0ZWQpKSwgbWF4KGMob3ZlcmFsbF9hdmVyYWdlX3RydWUsIG92ZXJhbGxfYXZlcmFnZV9leHBlY3RlZCkpKSkKI2xpbmVzKG92ZXJhbGxfYXZlcmFnZV9leHBlY3RlZCwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJyZWQiKQojbGVnZW5kKCJ0b3ByaWdodCIsIGxlZ2VuZCA9IGMoIlRydWUgVmFsdWVzIiwgIkV4cGVjdGVkIFZhbHVlcyIpLCBjb2wgPSBjKCJibHVlIiwgInJlZCIpLCBsdHkgPSAxLCBjZXggPSAwLjgpCgojIFBsb3QgdGhlIG92ZXJhbGwgYXZlcmFnZXMKcGxvdChvdmVyYWxsX2F2ZXJhZ2VfYmlkLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gImJsdWUiLCBtYWluID0gIk92ZXJhbGwgQXZlcmFnZSBvZiBCaWRzIHZzIEFza3MgJiBUcnVlIHZzIEV4cGVjdGVkIFZhbHVlcyIsIHhsYWIgPSAiUG9zaXRpb24gaW4gTGlzdCIsIHlsYWIgPSAiVmFsdWUiLCB5bGltID0gYyhtaW4oYyhvdmVyYWxsX2F2ZXJhZ2VfYmlkLCBvdmVyYWxsX2F2ZXJhZ2VfYXNrLCBvdmVyYWxsX2F2ZXJhZ2VfdHJ1ZSwgb3ZlcmFsbF9hdmVyYWdlX2V4cGVjdGVkKSksIG1heChjKG92ZXJhbGxfYXZlcmFnZV9iaWQsIG92ZXJhbGxfYXZlcmFnZV9hc2ssIG92ZXJhbGxfYXZlcmFnZV90cnVlLCBvdmVyYWxsX2F2ZXJhZ2VfZXhwZWN0ZWQpKSkpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9hc2ssIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAicmVkIikKbGluZXMob3ZlcmFsbF9hdmVyYWdlX3RydWUsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAiZ3JlZW4iKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfZXhwZWN0ZWQsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAicHVycGxlIikKbGVnZW5kKCJib3R0b21sZWZ0IiwgbGVnZW5kID0gYygiQmlkcyIsICJBc2tzIiwgIlRydWUgVmFsdWUiLCAiRXhwZWN0ZWQgVmFsdWUiKSwgY29sID0gYygiYmx1ZSIsICJyZWQiLCAiZ3JlZW4iLCAicHVycGxlIiksIGx0eSA9IDEsIGNleCA9IDAuOCkKYGBgCgoKYGBge3J9CiMgSW5pdGlhbGl6ZSBtYXRyaWNlcyB0byBzdG9yZSBhdmVyYWdlcyBmb3IgZWFjaCBwb3NpdGlvbgphdmVyYWdlX01NX3BubCA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKYXZlcmFnZV9NUjFfcG5sIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX01SMl9wbmwgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfTVIzX3BubCA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKYXZlcmFnZV9NUjRfcG5sIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX01SNV9wbmwgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfTVI2X3BubCA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKCiMgTG9vcCB0aHJvdWdoIGVhY2ggc2ltdWxhdGlvbiAobikKZm9yIChuIGluIDE6MTApIHsKCiAgTU1fcG5sX3NldDkgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzlbbiwgNl0pKSwgIiwgIikKCiAgTVIxX3BubF9zZXQ5IDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c185W24sIDhdKSksICIsICIpCiAgCiAgTVIyX3BubF9zZXQ5IDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c185W24sIDEwXSkpLCAiLCAiKQogIAogIE1SM19wbmxfc2V0OSA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfOVtuLCAxMl0pKSwgIiwgIikKICAKICBNUjRfcG5sX3NldDkgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzlbbiwgMTRdKSksICIsICIpCiAgCiAgTVI1X3BubF9zZXQ5IDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c185W24sIDE2XSkpLCAiLCAiKQogIAogIE1SNl9wbmxfc2V0OSA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfOVtuLCAxOF0pKSwgIiwgIikKICAKICAjIExvb3AgdGhyb3VnaCBlYWNoIHBvc2l0aW9uIChpKQogIGZvciAoaSBpbiAxOjEwMCkgewogICAgIyBFeHRyYWN0IFRydWUgYW5kIEV4cGVjdGVkIHZhbHVlcyBmb3IgdGhlIGktdGggcG9zaXRpb24KICAgIE1NX3BubCA8LSBzYXBwbHkoTU1fcG5sX3NldDksIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICBNUjFfcG5sIDwtIHNhcHBseShNUjFfcG5sX3NldDksIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICBNUjJfcG5sIDwtIHNhcHBseShNUjJfcG5sX3NldDksIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICBNUjNfcG5sIDwtIHNhcHBseShNUjNfcG5sX3NldDksIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICBNUjRfcG5sIDwtIHNhcHBseShNUjRfcG5sX3NldDksIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICBNUjVfcG5sIDwtIHNhcHBseShNUjVfcG5sX3NldDksIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICBNUjZfcG5sIDwtIHNhcHBseShNUjZfcG5sX3NldDksIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICAKICAgICMgQ2FsY3VsYXRlIHRoZSBhdmVyYWdlIG9mIFRydWUgYW5kIEV4cGVjdGVkIHZhbHVlcyBmb3IgdGhlIGktdGggcG9zaXRpb24KICAgIGF2ZXJhZ2VfTU1fcG5sW2ksIG5dIDwtIG1lYW4oTU1fcG5sLCBuYS5ybSA9IFRSVUUpCiAgICBhdmVyYWdlX01SMV9wbmxbaSwgbl0gPC0gbWVhbihNUjFfcG5sLCBuYS5ybSA9IFRSVUUpCiAgICBhdmVyYWdlX01SMl9wbmxbaSwgbl0gPC0gbWVhbihNUjJfcG5sLCBuYS5ybSA9IFRSVUUpCiAgICBhdmVyYWdlX01SM19wbmxbaSwgbl0gPC0gbWVhbihNUjNfcG5sLCBuYS5ybSA9IFRSVUUpCiAgICBhdmVyYWdlX01SNF9wbmxbaSwgbl0gPC0gbWVhbihNUjRfcG5sLCBuYS5ybSA9IFRSVUUpCiAgICBhdmVyYWdlX01SNV9wbmxbaSwgbl0gPC0gbWVhbihNUjVfcG5sLCBuYS5ybSA9IFRSVUUpCiAgICBhdmVyYWdlX01SNl9wbmxbaSwgbl0gPC0gbWVhbihNUjZfcG5sLCBuYS5ybSA9IFRSVUUpCiAgfQp9CgojIENhbGN1bGF0ZSB0aGUgb3ZlcmFsbCBhdmVyYWdlIGZvciBlYWNoIHBvc2l0aW9uIGFjcm9zcyBhbGwgc2ltdWxhdGlvbnMKb3ZlcmFsbF9hdmVyYWdlX01NX3BubCA8LSByb3dNZWFucyhhdmVyYWdlX01NX3BubCwgbmEucm0gPSBUUlVFKQpvdmVyYWxsX2F2ZXJhZ2VfTVIxX3BubCA8LSByb3dNZWFucyhhdmVyYWdlX01SMV9wbmwsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX01SMl9wbmwgPC0gcm93TWVhbnMoYXZlcmFnZV9NUjJfcG5sLCBuYS5ybSA9IFRSVUUpCm92ZXJhbGxfYXZlcmFnZV9NUjNfcG5sIDwtIHJvd01lYW5zKGF2ZXJhZ2VfTVIzX3BubCwgbmEucm0gPSBUUlVFKQpvdmVyYWxsX2F2ZXJhZ2VfTVI0X3BubCA8LSByb3dNZWFucyhhdmVyYWdlX01SNF9wbmwsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX01SNV9wbmwgPC0gcm93TWVhbnMoYXZlcmFnZV9NUjVfcG5sLCBuYS5ybSA9IFRSVUUpCm92ZXJhbGxfYXZlcmFnZV9NUjZfcG5sIDwtIHJvd01lYW5zKGF2ZXJhZ2VfTVI2X3BubCwgbmEucm0gPSBUUlVFKQoKIyBQbG90IHRoZSBvdmVyYWxsIGF2ZXJhZ2VzCnBsb3Qob3ZlcmFsbF9hdmVyYWdlX01NX3BubCwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJibGFjayIsIG1haW4gPSAiT3ZlcmFsbCBBdmVyYWdlIFBOTCIsIHhsYWIgPSAiUG9zaXRpb24gaW4gTGlzdCIsIHlsYWIgPSAiVmFsdWUiLCB5bGltID0gYyhtaW4oYyhvdmVyYWxsX2F2ZXJhZ2VfTU1fcG5sLCBvdmVyYWxsX2F2ZXJhZ2VfTVIxX3BubCwgb3ZlcmFsbF9hdmVyYWdlX01SMl9wbmwsIG92ZXJhbGxfYXZlcmFnZV9NUjNfcG5sLCBvdmVyYWxsX2F2ZXJhZ2VfTVI0X3BubCwgb3ZlcmFsbF9hdmVyYWdlX01SNV9wbmwsIG92ZXJhbGxfYXZlcmFnZV9NUjZfcG5sKSksIG1heChjKG92ZXJhbGxfYXZlcmFnZV9NTV9wbmwsIG92ZXJhbGxfYXZlcmFnZV9NUjFfcG5sLCBvdmVyYWxsX2F2ZXJhZ2VfTVIyX3BubCwgb3ZlcmFsbF9hdmVyYWdlX01SM19wbmwsIG92ZXJhbGxfYXZlcmFnZV9NUjRfcG5sLCBvdmVyYWxsX2F2ZXJhZ2VfTVI1X3BubCwgb3ZlcmFsbF9hdmVyYWdlX01SNl9wbmwpKSkpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9NUjFfcG5sLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gInJlZCIpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9NUjJfcG5sLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gImdyZWVuIikKbGluZXMob3ZlcmFsbF9hdmVyYWdlX01SM19wbmwsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAieWVsbG93IikKbGluZXMob3ZlcmFsbF9hdmVyYWdlX01SNF9wbmwsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAiYmx1ZSIpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9NUjVfcG5sLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gInB1cnBsZSIpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9NUjZfcG5sLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gIm9yYW5nZSIpCgojIEFkZCBsZWdlbmQKbGVnZW5kKCJib3R0b21sZWZ0IiwgbGVnZW5kID0gYygiTWFya2V0IE1ha2VyIiwgIk1SMSIsICJNUjIiLCAiTVIzIiwgIk1SNCIsICJNUjUiLCAiTVI2IiksIGNvbCA9IGMoImJsYWNrIiwgInJlZCIsICJncmVlbiIsICJ5ZWxsb3ciLCAiYmx1ZSIsICJwdXJwbGUiLCAib3JhbmdlIiksIGx0eSA9IDEsIGNleCA9IDAuOCkKYGBgCgpgYGB7cn0KIyBJbml0aWFsaXplIG1hdHJpY2VzIHRvIHN0b3JlIGF2ZXJhZ2VzIGZvciBlYWNoIHBvc2l0aW9uCmF2ZXJhZ2VfTU1fcG9zIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX01SMV9wb3MgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfTVIyX3BvcyA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKYXZlcmFnZV9NUjNfcG9zIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX01SNF9wb3MgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfTVI1X3BvcyA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKYXZlcmFnZV9NUjZfcG9zIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQoKIyBMb29wIHRocm91Z2ggZWFjaCBzaW11bGF0aW9uIChuKQpmb3IgKG4gaW4gMToxMCkgewoKICBNTV9wb3Nfc2V0OSA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfOVtuLCA3XSkpLCAiLCAiKQoKICBNUjFfcG9zX3NldDkgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzlbbiwgOV0pKSwgIiwgIikKICAKICBNUjJfcG9zX3NldDkgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzlbbiwgMTFdKSksICIsICIpCiAgCiAgTVIzX3Bvc19zZXQ5IDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c185W24sIDEzXSkpLCAiLCAiKQogIAogIE1SNF9wb3Nfc2V0OSA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfOVtuLCAxNV0pKSwgIiwgIikKICAKICBNUjVfcG9zX3NldDkgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzlbbiwgMTddKSksICIsICIpCiAgCiAgTVI2X3Bvc19zZXQ5IDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c185W24sIDE5XSkpLCAiLCAiKQogIAogICMgTG9vcCB0aHJvdWdoIGVhY2ggcG9zaXRpb24gKGkpCiAgZm9yIChpIGluIDE6MTAwKSB7CiAgICAjIEV4dHJhY3QgVHJ1ZSBhbmQgRXhwZWN0ZWQgdmFsdWVzIGZvciB0aGUgaS10aCBwb3NpdGlvbgogICAgTU1fcG9zIDwtIHNhcHBseShNTV9wb3Nfc2V0OSwgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIE1SMV9wb3MgPC0gc2FwcGx5KE1SMV9wb3Nfc2V0OSwgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIE1SMl9wb3MgPC0gc2FwcGx5KE1SMl9wb3Nfc2V0OSwgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIE1SM19wb3MgPC0gc2FwcGx5KE1SM19wb3Nfc2V0OSwgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIE1SNF9wb3MgPC0gc2FwcGx5KE1SNF9wb3Nfc2V0OSwgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIE1SNV9wb3MgPC0gc2FwcGx5KE1SNV9wb3Nfc2V0OSwgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIE1SNl9wb3MgPC0gc2FwcGx5KE1SNl9wb3Nfc2V0OSwgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIAogICAgIyBDYWxjdWxhdGUgdGhlIGF2ZXJhZ2Ugb2YgVHJ1ZSBhbmQgRXhwZWN0ZWQgdmFsdWVzIGZvciB0aGUgaS10aCBwb3NpdGlvbgogICAgYXZlcmFnZV9NTV9wb3NbaSwgbl0gPC0gbWVhbihNTV9wb3MsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfTVIxX3Bvc1tpLCBuXSA8LSBtZWFuKE1SMV9wb3MsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfTVIyX3Bvc1tpLCBuXSA8LSBtZWFuKE1SMl9wb3MsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfTVIzX3Bvc1tpLCBuXSA8LSBtZWFuKE1SM19wb3MsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfTVI0X3Bvc1tpLCBuXSA8LSBtZWFuKE1SNF9wb3MsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfTVI1X3Bvc1tpLCBuXSA8LSBtZWFuKE1SNV9wb3MsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfTVI2X3Bvc1tpLCBuXSA8LSBtZWFuKE1SNl9wb3MsIG5hLnJtID0gVFJVRSkKICB9Cn0KCiMgQ2FsY3VsYXRlIHRoZSBvdmVyYWxsIGF2ZXJhZ2UgZm9yIGVhY2ggcG9zaXRpb24gYWNyb3NzIGFsbCBzaW11bGF0aW9ucwpvdmVyYWxsX2F2ZXJhZ2VfTU1fcG9zIDwtIHJvd01lYW5zKGF2ZXJhZ2VfTU1fcG9zLCBuYS5ybSA9IFRSVUUpCm92ZXJhbGxfYXZlcmFnZV9NUjFfcG9zIDwtIHJvd01lYW5zKGF2ZXJhZ2VfTVIxX3BvcywgbmEucm0gPSBUUlVFKQpvdmVyYWxsX2F2ZXJhZ2VfTVIyX3BvcyA8LSByb3dNZWFucyhhdmVyYWdlX01SMl9wb3MsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX01SM19wb3MgPC0gcm93TWVhbnMoYXZlcmFnZV9NUjNfcG9zLCBuYS5ybSA9IFRSVUUpCm92ZXJhbGxfYXZlcmFnZV9NUjRfcG9zIDwtIHJvd01lYW5zKGF2ZXJhZ2VfTVI0X3BvcywgbmEucm0gPSBUUlVFKQpvdmVyYWxsX2F2ZXJhZ2VfTVI1X3BvcyA8LSByb3dNZWFucyhhdmVyYWdlX01SNV9wb3MsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX01SNl9wb3MgPC0gcm93TWVhbnMoYXZlcmFnZV9NUjZfcG9zLCBuYS5ybSA9IFRSVUUpCgojIFBsb3QgdGhlIG92ZXJhbGwgYXZlcmFnZXMKcGxvdChvdmVyYWxsX2F2ZXJhZ2VfTU1fcG9zLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gImJsYWNrIiwgbWFpbiA9ICJPdmVyYWxsIEF2ZXJhZ2UgUG9zaXRpb24iLCB4bGFiID0gIlBvc2l0aW9uIGluIExpc3QiLCB5bGFiID0gIlZhbHVlIiwgeWxpbSA9IGMobWluKGMob3ZlcmFsbF9hdmVyYWdlX01NX3Bvcywgb3ZlcmFsbF9hdmVyYWdlX01SMV9wb3MsIG92ZXJhbGxfYXZlcmFnZV9NUjJfcG9zLCBvdmVyYWxsX2F2ZXJhZ2VfTVIzX3Bvcywgb3ZlcmFsbF9hdmVyYWdlX01SNF9wb3MsIG92ZXJhbGxfYXZlcmFnZV9NUjVfcG9zLCBvdmVyYWxsX2F2ZXJhZ2VfTVI2X3BvcykpLCBtYXgoYyhvdmVyYWxsX2F2ZXJhZ2VfTU1fcG9zLCBvdmVyYWxsX2F2ZXJhZ2VfTVIxX3Bvcywgb3ZlcmFsbF9hdmVyYWdlX01SMl9wb3MsIG92ZXJhbGxfYXZlcmFnZV9NUjNfcG9zLCBvdmVyYWxsX2F2ZXJhZ2VfTVI0X3Bvcywgb3ZlcmFsbF9hdmVyYWdlX01SNV9wb3MsIG92ZXJhbGxfYXZlcmFnZV9NUjZfcG9zKSkpKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfTVIxX3BvcywgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJyZWQiKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfTVIyX3BvcywgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJncmVlbiIpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9NUjNfcG9zLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gInllbGxvdyIpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9NUjRfcG9zLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gImJsdWUiKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfTVI1X3BvcywgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJwdXJwbGUiKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfTVI2X3BvcywgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJvcmFuZ2UiKQoKIyBBZGQgbGVnZW5kCmxlZ2VuZCgiYm90dG9tbGVmdCIsIGxlZ2VuZCA9IGMoIk1hcmtldCBNYWtlciIsICJNUjEiLCAiTVIyIiwgIk1SMyIsICJNUjQiLCAiTVI1IiwgIk1SNiIpLCBjb2wgPSBjKCJibGFjayIsICJyZWQiLCAiZ3JlZW4iLCAieWVsbG93IiwgImJsdWUiLCAicHVycGxlIiwgIm9yYW5nZSIpLCBsdHkgPSAxLCBjZXggPSAwLjgpCmBgYAoKIyMgc2V0MTAgKE1vbSA6IDYpCgpgYGB7cn0KIyBJbml0aWFsaXplIG1hdHJpY2VzIHRvIHN0b3JlIGF2ZXJhZ2VzIGZvciBlYWNoIHBvc2l0aW9uCmF2ZXJhZ2VfdHJ1ZSA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKYXZlcmFnZV9leHBlY3RlZCA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKCiMgTG9vcCB0aHJvdWdoIGVhY2ggc2ltdWxhdGlvbiAobikKZm9yIChuIGluIDE6MTApIHsKICAjIEV4dHJhY3QgVHJ1ZSB2YWx1ZXMgZnJvbSB0aGUgYWdncmVnYXRlZF9yZXN1bHRzXzQgZGF0YWZyYW1lCiAgVHJ1ZVZhbHVlc19zZXQxMCA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfMTBbbiwgMl0pKSwgIiwgIikKICAKICAjIEV4dHJhY3QgRXhwZWN0ZWQgdmFsdWVzIGZyb20gdGhlIGFnZ3JlZ2F0ZWRfcmVzdWx0c180IGRhdGFmcmFtZQogIEV4cGVjdGVkVmFsdWVzX3NldDEwIDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c18xMFtuLCAzXSkpLCAiLCAiKQogIAogICMgTG9vcCB0aHJvdWdoIGVhY2ggcG9zaXRpb24gKGkpCiAgZm9yIChpIGluIDE6MTAwKSB7CiAgICAjIEV4dHJhY3QgVHJ1ZSBhbmQgRXhwZWN0ZWQgdmFsdWVzIGZvciB0aGUgaS10aCBwb3NpdGlvbgogICAgVHJ1ZV92YWx1ZXMgPC0gc2FwcGx5KFRydWVWYWx1ZXNfc2V0MTAsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICBFeHBlY3RlZF92YWx1ZXMgPC0gc2FwcGx5KEV4cGVjdGVkVmFsdWVzX3NldDEwLCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgCiAgICAjIENhbGN1bGF0ZSB0aGUgYXZlcmFnZSBvZiBUcnVlIGFuZCBFeHBlY3RlZCB2YWx1ZXMgZm9yIHRoZSBpLXRoIHBvc2l0aW9uCiAgICBhdmVyYWdlX3RydWVbaSwgbl0gPC0gbWVhbihUcnVlX3ZhbHVlcywgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9leHBlY3RlZFtpLCBuXSA8LSBtZWFuKEV4cGVjdGVkX3ZhbHVlcywgbmEucm0gPSBUUlVFKQogIH0KfQoKIyBDYWxjdWxhdGUgdGhlIG92ZXJhbGwgYXZlcmFnZSBmb3IgZWFjaCBwb3NpdGlvbiBhY3Jvc3MgYWxsIHNpbXVsYXRpb25zCm92ZXJhbGxfYXZlcmFnZV90cnVlIDwtIHJvd01lYW5zKGF2ZXJhZ2VfdHJ1ZSwgbmEucm0gPSBUUlVFKQpvdmVyYWxsX2F2ZXJhZ2VfZXhwZWN0ZWQgPC0gcm93TWVhbnMoYXZlcmFnZV9leHBlY3RlZCwgbmEucm0gPSBUUlVFKQoKIyBQbG90IHRoZSBvdmVyYWxsIGF2ZXJhZ2VzCnBsb3Qob3ZlcmFsbF9hdmVyYWdlX3RydWUsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAiYmx1ZSIsIG1haW4gPSAiT3ZlcmFsbCBBdmVyYWdlIG9mIFRydWUgdnMgRXhwZWN0ZWQgVmFsdWVzIiwgeGxhYiA9ICJQb3NpdGlvbiBpbiBMaXN0IiwgeWxhYiA9ICJWYWx1ZSIsIHlsaW0gPSBjKG1pbihjKG92ZXJhbGxfYXZlcmFnZV90cnVlLCBvdmVyYWxsX2F2ZXJhZ2VfZXhwZWN0ZWQpKSwgbWF4KGMob3ZlcmFsbF9hdmVyYWdlX3RydWUsIG92ZXJhbGxfYXZlcmFnZV9leHBlY3RlZCkpKSkKbGluZXMob3ZlcmFsbF9hdmVyYWdlX2V4cGVjdGVkLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gInJlZCIpCmxlZ2VuZCgidG9wcmlnaHQiLCBsZWdlbmQgPSBjKCJUcnVlIFZhbHVlcyIsICJFeHBlY3RlZCBWYWx1ZXMiKSwgY29sID0gYygiYmx1ZSIsICJyZWQiKSwgbHR5ID0gMSwgY2V4ID0gMC44KQpgYGAKCgoKCmBgYHtyfQojIEluaXRpYWxpemUgbWF0cmljZXMgdG8gc3RvcmUgYXZlcmFnZXMgZm9yIGVhY2ggcG9zaXRpb24KYXZlcmFnZV9iaWQgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfYXNrIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQoKIyBMb29wIHRocm91Z2ggZWFjaCBzaW11bGF0aW9uIChuKQpmb3IgKG4gaW4gMToxMCkgewogICMgRXh0cmFjdCBUcnVlIHZhbHVlcyBmcm9tIHRoZSBhZ2dyZWdhdGVkX3Jlc3VsdHNfNCBkYXRhZnJhbWUKICBCaWRzX3NldDEwIDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c18xMFtuLCA0XSkpLCAiLCAiKQogIAogICMgRXh0cmFjdCBFeHBlY3RlZCB2YWx1ZXMgZnJvbSB0aGUgYWdncmVnYXRlZF9yZXN1bHRzXzQgZGF0YWZyYW1lCiAgQXNrc19zZXQxMCA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfMTBbbiwgNV0pKSwgIiwgIikKICAKICAjIExvb3AgdGhyb3VnaCBlYWNoIHBvc2l0aW9uIChpKQogIGZvciAoaSBpbiAxOjEwMCkgewogICAgIyBFeHRyYWN0IFRydWUgYW5kIEV4cGVjdGVkIHZhbHVlcyBmb3IgdGhlIGktdGggcG9zaXRpb24KICAgIEJpZHMgPC0gc2FwcGx5KEJpZHNfc2V0MTAsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICBBc2tzIDwtIHNhcHBseShBc2tzX3NldDEwLCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgCiAgICAjIENhbGN1bGF0ZSB0aGUgYXZlcmFnZSBvZiBUcnVlIGFuZCBFeHBlY3RlZCB2YWx1ZXMgZm9yIHRoZSBpLXRoIHBvc2l0aW9uCiAgICBhdmVyYWdlX2JpZFtpLCBuXSA8LSBtZWFuKEJpZHMsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfYXNrW2ksIG5dIDwtIG1lYW4oQXNrcywgbmEucm0gPSBUUlVFKQogIH0KfQoKIyBDYWxjdWxhdGUgdGhlIG92ZXJhbGwgYXZlcmFnZSBmb3IgZWFjaCBwb3NpdGlvbiBhY3Jvc3MgYWxsIHNpbXVsYXRpb25zCm92ZXJhbGxfYXZlcmFnZV9iaWQgPC0gcm93TWVhbnMoYXZlcmFnZV9iaWQsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX2FzayA8LSByb3dNZWFucyhhdmVyYWdlX2FzaywgbmEucm0gPSBUUlVFKQoKIyBQbG90IHRoZSBvdmVyYWxsIGF2ZXJhZ2VzCnBsb3Qob3ZlcmFsbF9hdmVyYWdlX2JpZCwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJibHVlIiwgbWFpbiA9ICJPdmVyYWxsIEF2ZXJhZ2Ugb2YgQmlkcyB2cyBBc2tzIiwgeGxhYiA9ICJQb3NpdGlvbiBpbiBMaXN0IiwgeWxhYiA9ICJWYWx1ZSIsIHlsaW0gPSBjKG1pbihjKG92ZXJhbGxfYXZlcmFnZV9iaWQsIG92ZXJhbGxfYXZlcmFnZV9hc2spKSwgbWF4KGMob3ZlcmFsbF9hdmVyYWdlX2JpZCwgb3ZlcmFsbF9hdmVyYWdlX2FzaykpKSkKbGluZXMob3ZlcmFsbF9hdmVyYWdlX2FzaywgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJyZWQiKQpsZWdlbmQoInRvcHJpZ2h0IiwgbGVnZW5kID0gYygiQmlkcyIsICJBc2tzIiksIGNvbCA9IGMoImJsdWUiLCAicmVkIiksIGx0eSA9IDEsIGNleCA9IDAuOCkKYGBgCgpgYGB7cn0KIyBJbml0aWFsaXplIG1hdHJpY2VzIHRvIHN0b3JlIGF2ZXJhZ2VzIGZvciBlYWNoIHBvc2l0aW9uCmF2ZXJhZ2VfYmlkIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX2FzayA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKCiMgTG9vcCB0aHJvdWdoIGVhY2ggc2ltdWxhdGlvbiAobikKZm9yIChuIGluIDE6MTApIHsKICAjIEV4dHJhY3QgVHJ1ZSB2YWx1ZXMgZnJvbSB0aGUgYWdncmVnYXRlZF9yZXN1bHRzXzQgZGF0YWZyYW1lCiAgQmlkc19zZXQxMCA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfMTBbbiwgNF0pKSwgIiwgIikKICAKICAjIEV4dHJhY3QgRXhwZWN0ZWQgdmFsdWVzIGZyb20gdGhlIGFnZ3JlZ2F0ZWRfcmVzdWx0c180IGRhdGFmcmFtZQogIEFza3Nfc2V0MTAgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzEwW24sIDVdKSksICIsICIpCiAgCiAgIyBMb29wIHRocm91Z2ggZWFjaCBwb3NpdGlvbiAoaSkKICBmb3IgKGkgaW4gMToxMDApIHsKICAgICMgRXh0cmFjdCBUcnVlIGFuZCBFeHBlY3RlZCB2YWx1ZXMgZm9yIHRoZSBpLXRoIHBvc2l0aW9uCiAgICBCaWRzIDwtIHNhcHBseShCaWRzX3NldDEwLCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgQXNrcyA8LSBzYXBwbHkoQXNrc19zZXQxMCwgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIAogICAgIyBDYWxjdWxhdGUgdGhlIGF2ZXJhZ2Ugb2YgVHJ1ZSBhbmQgRXhwZWN0ZWQgdmFsdWVzIGZvciB0aGUgaS10aCBwb3NpdGlvbgogICAgYXZlcmFnZV9iaWRbaSwgbl0gPC0gbWVhbihCaWRzLCBuYS5ybSA9IFRSVUUpCiAgICBhdmVyYWdlX2Fza1tpLCBuXSA8LSBtZWFuKEFza3MsIG5hLnJtID0gVFJVRSkKICB9Cn0KCiMgQ2FsY3VsYXRlIHRoZSBvdmVyYWxsIGF2ZXJhZ2UgZm9yIGVhY2ggcG9zaXRpb24gYWNyb3NzIGFsbCBzaW11bGF0aW9ucwpvdmVyYWxsX2F2ZXJhZ2VfYmlkIDwtIHJvd01lYW5zKGF2ZXJhZ2VfYmlkLCBuYS5ybSA9IFRSVUUpCm92ZXJhbGxfYXZlcmFnZV9hc2sgPC0gcm93TWVhbnMoYXZlcmFnZV9hc2ssIG5hLnJtID0gVFJVRSkKCiMjIFRydWUgVmFsdWUKIyBJbml0aWFsaXplIG1hdHJpY2VzIHRvIHN0b3JlIGF2ZXJhZ2VzIGZvciBlYWNoIHBvc2l0aW9uCmF2ZXJhZ2VfdHJ1ZSA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKYXZlcmFnZV9leHBlY3RlZCA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKCiMgTG9vcCB0aHJvdWdoIGVhY2ggc2ltdWxhdGlvbiAobikKZm9yIChuIGluIDE6MTApIHsKICAjIEV4dHJhY3QgVHJ1ZSB2YWx1ZXMgZnJvbSB0aGUgYWdncmVnYXRlZF9yZXN1bHRzXzQgZGF0YWZyYW1lCiAgVHJ1ZVZhbHVlc19zZXQxMCA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfMTBbbiwgMl0pKSwgIiwgIikKICAKICAjIEV4dHJhY3QgRXhwZWN0ZWQgdmFsdWVzIGZyb20gdGhlIGFnZ3JlZ2F0ZWRfcmVzdWx0c180IGRhdGFmcmFtZQogIEV4cGVjdGVkVmFsdWVzX3NldDEwIDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c18xMFtuLCAzXSkpLCAiLCAiKQogIAogICMgTG9vcCB0aHJvdWdoIGVhY2ggcG9zaXRpb24gKGkpCiAgZm9yIChpIGluIDE6MTAwKSB7CiAgICAjIEV4dHJhY3QgVHJ1ZSBhbmQgRXhwZWN0ZWQgdmFsdWVzIGZvciB0aGUgaS10aCBwb3NpdGlvbgogICAgVHJ1ZV92YWx1ZXMgPC0gc2FwcGx5KFRydWVWYWx1ZXNfc2V0MTAsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICBFeHBlY3RlZF92YWx1ZXMgPC0gc2FwcGx5KEV4cGVjdGVkVmFsdWVzX3NldDEsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICAKICAgICMgQ2FsY3VsYXRlIHRoZSBhdmVyYWdlIG9mIFRydWUgYW5kIEV4cGVjdGVkIHZhbHVlcyBmb3IgdGhlIGktdGggcG9zaXRpb24KICAgIGF2ZXJhZ2VfdHJ1ZVtpLCBuXSA8LSBtZWFuKFRydWVfdmFsdWVzLCBuYS5ybSA9IFRSVUUpCiAgICBhdmVyYWdlX2V4cGVjdGVkW2ksIG5dIDwtIG1lYW4oRXhwZWN0ZWRfdmFsdWVzLCBuYS5ybSA9IFRSVUUpCiAgfQp9CgojIENhbGN1bGF0ZSB0aGUgb3ZlcmFsbCBhdmVyYWdlIGZvciBlYWNoIHBvc2l0aW9uIGFjcm9zcyBhbGwgc2ltdWxhdGlvbnMKb3ZlcmFsbF9hdmVyYWdlX3RydWUgPC0gcm93TWVhbnMoYXZlcmFnZV90cnVlLCBuYS5ybSA9IFRSVUUpCm92ZXJhbGxfYXZlcmFnZV9leHBlY3RlZCA8LSByb3dNZWFucyhhdmVyYWdlX2V4cGVjdGVkLCBuYS5ybSA9IFRSVUUpCgojIFBsb3QgdGhlIG92ZXJhbGwgYXZlcmFnZXMKI3Bsb3Qob3ZlcmFsbF9hdmVyYWdlX3RydWUsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAiYmx1ZSIsIG1haW4gPSAiT3ZlcmFsbCBBdmVyYWdlIG9mIFRydWUgdnMgRXhwZWN0ZWQgVmFsdWVzIiwgeGxhYiA9ICJQb3NpdGlvbiBpbiBMaXN0IiwgeWxhYiA9ICJWYWx1ZSIsIHlsaW0gPSBjKG1pbihjKG92ZXJhbGxfYXZlcmFnZV90cnVlLCBvdmVyYWxsX2F2ZXJhZ2VfZXhwZWN0ZWQpKSwgbWF4KGMob3ZlcmFsbF9hdmVyYWdlX3RydWUsIG92ZXJhbGxfYXZlcmFnZV9leHBlY3RlZCkpKSkKI2xpbmVzKG92ZXJhbGxfYXZlcmFnZV9leHBlY3RlZCwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJyZWQiKQojbGVnZW5kKCJ0b3ByaWdodCIsIGxlZ2VuZCA9IGMoIlRydWUgVmFsdWVzIiwgIkV4cGVjdGVkIFZhbHVlcyIpLCBjb2wgPSBjKCJibHVlIiwgInJlZCIpLCBsdHkgPSAxLCBjZXggPSAwLjgpCgojIFBsb3QgdGhlIG92ZXJhbGwgYXZlcmFnZXMKcGxvdChvdmVyYWxsX2F2ZXJhZ2VfYmlkLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gImJsdWUiLCBtYWluID0gIk92ZXJhbGwgQXZlcmFnZSBvZiBCaWRzIHZzIEFza3MgJiBUcnVlIHZzIEV4cGVjdGVkIFZhbHVlcyIsIHhsYWIgPSAiUG9zaXRpb24gaW4gTGlzdCIsIHlsYWIgPSAiVmFsdWUiLCB5bGltID0gYyhtaW4oYyhvdmVyYWxsX2F2ZXJhZ2VfYmlkLCBvdmVyYWxsX2F2ZXJhZ2VfYXNrLCBvdmVyYWxsX2F2ZXJhZ2VfdHJ1ZSwgb3ZlcmFsbF9hdmVyYWdlX2V4cGVjdGVkKSksIG1heChjKG92ZXJhbGxfYXZlcmFnZV9iaWQsIG92ZXJhbGxfYXZlcmFnZV9hc2ssIG92ZXJhbGxfYXZlcmFnZV90cnVlLCBvdmVyYWxsX2F2ZXJhZ2VfZXhwZWN0ZWQpKSkpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9hc2ssIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAicmVkIikKbGluZXMob3ZlcmFsbF9hdmVyYWdlX3RydWUsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAiZ3JlZW4iKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfZXhwZWN0ZWQsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAicHVycGxlIikKbGVnZW5kKCJib3R0b21sZWZ0IiwgbGVnZW5kID0gYygiQmlkcyIsICJBc2tzIiwgIlRydWUgVmFsdWUiLCAiRXhwZWN0ZWQgVmFsdWUiKSwgY29sID0gYygiYmx1ZSIsICJyZWQiLCAiZ3JlZW4iLCAicHVycGxlIiksIGx0eSA9IDEsIGNleCA9IDAuOCkKYGBgCgoKCmBgYHtyfQojIEluaXRpYWxpemUgbWF0cmljZXMgdG8gc3RvcmUgYXZlcmFnZXMgZm9yIGVhY2ggcG9zaXRpb24KYXZlcmFnZV9NTV9wbmwgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfTW9tMV9wbmwgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfTW9tMl9wbmwgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfTW9tM19wbmwgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfTW9tNF9wbmwgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfTW9tNV9wbmwgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfTW9tNl9wbmwgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCgojIExvb3AgdGhyb3VnaCBlYWNoIHNpbXVsYXRpb24gKG4pCmZvciAobiBpbiAxOjEwKSB7CgogIE1NX3BubF9zZXQxMCA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfMTBbbiwgNl0pKSwgIiwgIikKCiAgTW9tMV9wbmxfc2V0MTAgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzEwW24sIDhdKSksICIsICIpCiAgCiAgTW9tMl9wbmxfc2V0MTAgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzEwW24sIDEwXSkpLCAiLCAiKQogIAogIE1vbTNfcG5sX3NldDEwIDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c18xMFtuLCAxMl0pKSwgIiwgIikKICAKICBNb200X3BubF9zZXQxMCA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfMTBbbiwgMTRdKSksICIsICIpCiAgCiAgTW9tNV9wbmxfc2V0MTAgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzEwW24sIDE2XSkpLCAiLCAiKQogIAogIE1vbTZfcG5sX3NldDEwIDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c18xMFtuLCAxOF0pKSwgIiwgIikKICAKICAjIExvb3AgdGhyb3VnaCBlYWNoIHBvc2l0aW9uIChpKQogIGZvciAoaSBpbiAxOjEwMCkgewogICAgIyBFeHRyYWN0IFRydWUgYW5kIEV4cGVjdGVkIHZhbHVlcyBmb3IgdGhlIGktdGggcG9zaXRpb24KICAgIE1NX3BubCA8LSBzYXBwbHkoTU1fcG5sX3NldDEwLCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgTW9tMV9wbmwgPC0gc2FwcGx5KE1vbTFfcG5sX3NldDEwLCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgTW9tMl9wbmwgPC0gc2FwcGx5KE1vbTJfcG5sX3NldDEwLCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgTW9tM19wbmwgPC0gc2FwcGx5KE1vbTNfcG5sX3NldDEwLCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgTW9tNF9wbmwgPC0gc2FwcGx5KE1vbTRfcG5sX3NldDEwLCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgTW9tNV9wbmwgPC0gc2FwcGx5KE1vbTVfcG5sX3NldDEwLCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgTW9tNl9wbmwgPC0gc2FwcGx5KE1vbTZfcG5sX3NldDEwLCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgCiAgICAjIENhbGN1bGF0ZSB0aGUgYXZlcmFnZSBvZiBUcnVlIGFuZCBFeHBlY3RlZCB2YWx1ZXMgZm9yIHRoZSBpLXRoIHBvc2l0aW9uCiAgICBhdmVyYWdlX01NX3BubFtpLCBuXSA8LSBtZWFuKE1NX3BubCwgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9Nb20xX3BubFtpLCBuXSA8LSBtZWFuKE1vbTFfcG5sLCBuYS5ybSA9IFRSVUUpCiAgICBhdmVyYWdlX01vbTJfcG5sW2ksIG5dIDwtIG1lYW4oTW9tMl9wbmwsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfTW9tM19wbmxbaSwgbl0gPC0gbWVhbihNb20zX3BubCwgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9Nb200X3BubFtpLCBuXSA8LSBtZWFuKE1vbTRfcG5sLCBuYS5ybSA9IFRSVUUpCiAgICBhdmVyYWdlX01vbTVfcG5sW2ksIG5dIDwtIG1lYW4oTW9tNV9wbmwsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfTW9tNl9wbmxbaSwgbl0gPC0gbWVhbihNb202X3BubCwgbmEucm0gPSBUUlVFKQogIH0KfQoKIyBDYWxjdWxhdGUgdGhlIG92ZXJhbGwgYXZlcmFnZSBmb3IgZWFjaCBwb3NpdGlvbiBhY3Jvc3MgYWxsIHNpbXVsYXRpb25zCm92ZXJhbGxfYXZlcmFnZV9NTV9wbmwgPC0gcm93TWVhbnMoYXZlcmFnZV9NTV9wbmwsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX01vbTFfcG5sIDwtIHJvd01lYW5zKGF2ZXJhZ2VfTW9tMV9wbmwsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX01vbTJfcG5sIDwtIHJvd01lYW5zKGF2ZXJhZ2VfTW9tMl9wbmwsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX01vbTNfcG5sIDwtIHJvd01lYW5zKGF2ZXJhZ2VfTW9tM19wbmwsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX01vbTRfcG5sIDwtIHJvd01lYW5zKGF2ZXJhZ2VfTW9tNF9wbmwsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX01vbTVfcG5sIDwtIHJvd01lYW5zKGF2ZXJhZ2VfTW9tNV9wbmwsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX01vbTZfcG5sIDwtIHJvd01lYW5zKGF2ZXJhZ2VfTW9tNl9wbmwsIG5hLnJtID0gVFJVRSkKCiMgUGxvdCB0aGUgb3ZlcmFsbCBhdmVyYWdlcwpwbG90KG92ZXJhbGxfYXZlcmFnZV9NTV9wbmwsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAiYmxhY2siLCBtYWluID0gIk92ZXJhbGwgQXZlcmFnZSBQTkwiLCB4bGFiID0gIlBvc2l0aW9uIGluIExpc3QiLCB5bGFiID0gIlZhbHVlIiwgeWxpbSA9IGMobWluKGMob3ZlcmFsbF9hdmVyYWdlX01NX3BubCwgb3ZlcmFsbF9hdmVyYWdlX01vbTFfcG5sLCBvdmVyYWxsX2F2ZXJhZ2VfTW9tMl9wbmwsIG92ZXJhbGxfYXZlcmFnZV9Nb20zX3BubCwgb3ZlcmFsbF9hdmVyYWdlX01vbTRfcG5sLCBvdmVyYWxsX2F2ZXJhZ2VfTW9tNV9wbmwsIG92ZXJhbGxfYXZlcmFnZV9Nb202X3BubCkpLCBtYXgoYyhvdmVyYWxsX2F2ZXJhZ2VfTU1fcG5sLCBvdmVyYWxsX2F2ZXJhZ2VfTW9tMV9wbmwsIG92ZXJhbGxfYXZlcmFnZV9Nb20yX3BubCwgb3ZlcmFsbF9hdmVyYWdlX01vbTNfcG5sLCBvdmVyYWxsX2F2ZXJhZ2VfTW9tNF9wbmwsIG92ZXJhbGxfYXZlcmFnZV9Nb201X3BubCwgb3ZlcmFsbF9hdmVyYWdlX01vbTZfcG5sKSkpKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfTW9tMV9wbmwsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAicmVkIikKbGluZXMob3ZlcmFsbF9hdmVyYWdlX01vbTJfcG5sLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gImdyZWVuIikKbGluZXMob3ZlcmFsbF9hdmVyYWdlX01vbTNfcG5sLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gInllbGxvdyIpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9Nb200X3BubCwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJibHVlIikKbGluZXMob3ZlcmFsbF9hdmVyYWdlX01vbTVfcG5sLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gInB1cnBsZSIpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9Nb202X3BubCwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJvcmFuZ2UiKQoKIyBBZGQgbGVnZW5kCmxlZ2VuZCgiYm90dG9tbGVmdCIsIGxlZ2VuZCA9IGMoIk1hcmtldCBNYWtlciIsICJJbmZvcm1lZCIsICJNb20xIiwgIk1vbTIiLCAiTW9tMyIsICJNb200IiwgIk1vbTUiKSwgY29sID0gYygiYmxhY2siLCAicmVkIiwgImdyZWVuIiwgInllbGxvdyIsICJibHVlIiwgInB1cnBsZSIsICJvcmFuZ2UiKSwgbHR5ID0gMSwgY2V4ID0gMC44KQpgYGAKCmBgYHtyfQojIEluaXRpYWxpemUgbWF0cmljZXMgdG8gc3RvcmUgYXZlcmFnZXMgZm9yIGVhY2ggcG9zaXRpb24KYXZlcmFnZV9NTV9wb3MgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfTW9tMV9wb3MgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfTW9tMl9wb3MgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfTW9tM19wb3MgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfTW9tNF9wb3MgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfTW9tNV9wb3MgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfTW9tNl9wb3MgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCgojIExvb3AgdGhyb3VnaCBlYWNoIHNpbXVsYXRpb24gKG4pCmZvciAobiBpbiAxOjEwKSB7CgogIE1NX3Bvc19zZXQxMCA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfMTBbbiwgN10pKSwgIiwgIikKCiAgTW9tMV9wb3Nfc2V0MTAgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzEwW24sIDldKSksICIsICIpCiAgCiAgTW9tMl9wb3Nfc2V0MTAgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzEwW24sIDExXSkpLCAiLCAiKQogIAogIE1vbTNfcG9zX3NldDEwIDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c18xMFtuLCAxM10pKSwgIiwgIikKICAKICBNb200X3Bvc19zZXQxMCA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfMTBbbiwgMTVdKSksICIsICIpCiAgCiAgTW9tNV9wb3Nfc2V0MTAgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzEwW24sIDE3XSkpLCAiLCAiKQogIAogIE1vbTZfcG9zX3NldDEwIDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c18xMFtuLCAxOV0pKSwgIiwgIikKICAKICAjIExvb3AgdGhyb3VnaCBlYWNoIHBvc2l0aW9uIChpKQogIGZvciAoaSBpbiAxOjEwMCkgewogICAgIyBFeHRyYWN0IFRydWUgYW5kIEV4cGVjdGVkIHZhbHVlcyBmb3IgdGhlIGktdGggcG9zaXRpb24KICAgIE1NX3BvcyA8LSBzYXBwbHkoTU1fcG9zX3NldDEwLCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgTW9tMV9wb3MgPC0gc2FwcGx5KE1vbTFfcG9zX3NldDEwLCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgTW9tMl9wb3MgPC0gc2FwcGx5KE1vbTJfcG9zX3NldDEwLCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgTW9tM19wb3MgPC0gc2FwcGx5KE1vbTNfcG9zX3NldDEwLCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgTW9tNF9wb3MgPC0gc2FwcGx5KE1vbTRfcG9zX3NldDEwLCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgTW9tNV9wb3MgPC0gc2FwcGx5KE1vbTVfcG9zX3NldDEwLCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgTW9tNl9wb3MgPC0gc2FwcGx5KE1vbTZfcG9zX3NldDEwLCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgCiAgICAjIENhbGN1bGF0ZSB0aGUgYXZlcmFnZSBvZiBUcnVlIGFuZCBFeHBlY3RlZCB2YWx1ZXMgZm9yIHRoZSBpLXRoIHBvc2l0aW9uCiAgICBhdmVyYWdlX01NX3Bvc1tpLCBuXSA8LSBtZWFuKE1NX3BvcywgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9Nb20xX3Bvc1tpLCBuXSA8LSBtZWFuKE1vbTFfcG9zLCBuYS5ybSA9IFRSVUUpCiAgICBhdmVyYWdlX01vbTJfcG9zW2ksIG5dIDwtIG1lYW4oTW9tMl9wb3MsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfTW9tM19wb3NbaSwgbl0gPC0gbWVhbihNb20zX3BvcywgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9Nb200X3Bvc1tpLCBuXSA8LSBtZWFuKE1vbTRfcG9zLCBuYS5ybSA9IFRSVUUpCiAgICBhdmVyYWdlX01vbTVfcG9zW2ksIG5dIDwtIG1lYW4oTW9tNV9wb3MsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfTW9tNl9wb3NbaSwgbl0gPC0gbWVhbihNb202X3BvcywgbmEucm0gPSBUUlVFKQogIH0KfQoKIyBDYWxjdWxhdGUgdGhlIG92ZXJhbGwgYXZlcmFnZSBmb3IgZWFjaCBwb3NpdGlvbiBhY3Jvc3MgYWxsIHNpbXVsYXRpb25zCm92ZXJhbGxfYXZlcmFnZV9NTV9wb3MgPC0gcm93TWVhbnMoYXZlcmFnZV9NTV9wb3MsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX01vbTFfcG9zIDwtIHJvd01lYW5zKGF2ZXJhZ2VfTW9tMV9wb3MsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX01vbTJfcG9zIDwtIHJvd01lYW5zKGF2ZXJhZ2VfTW9tMl9wb3MsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX01vbTNfcG9zIDwtIHJvd01lYW5zKGF2ZXJhZ2VfTW9tM19wb3MsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX01vbTRfcG9zIDwtIHJvd01lYW5zKGF2ZXJhZ2VfTW9tNF9wb3MsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX01vbTVfcG9zIDwtIHJvd01lYW5zKGF2ZXJhZ2VfTW9tNV9wb3MsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX01vbTZfcG9zIDwtIHJvd01lYW5zKGF2ZXJhZ2VfTW9tNl9wb3MsIG5hLnJtID0gVFJVRSkKCiMgUGxvdCB0aGUgb3ZlcmFsbCBhdmVyYWdlcwpwbG90KG92ZXJhbGxfYXZlcmFnZV9NTV9wb3MsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAiYmxhY2siLCBtYWluID0gIk92ZXJhbGwgQXZlcmFnZSBQb3NpdGlvbiIsIHhsYWIgPSAiUG9zaXRpb24gaW4gTGlzdCIsIHlsYWIgPSAiVmFsdWUiLCB5bGltID0gYyhtaW4oYyhvdmVyYWxsX2F2ZXJhZ2VfTU1fcG9zLCBvdmVyYWxsX2F2ZXJhZ2VfTW9tMV9wb3MsIG92ZXJhbGxfYXZlcmFnZV9Nb20yX3Bvcywgb3ZlcmFsbF9hdmVyYWdlX01vbTNfcG9zLCBvdmVyYWxsX2F2ZXJhZ2VfTW9tNF9wb3MsIG92ZXJhbGxfYXZlcmFnZV9Nb201X3Bvcywgb3ZlcmFsbF9hdmVyYWdlX01vbTZfcG9zKSksIG1heChjKG92ZXJhbGxfYXZlcmFnZV9NTV9wb3MsIG92ZXJhbGxfYXZlcmFnZV9Nb20xX3Bvcywgb3ZlcmFsbF9hdmVyYWdlX01vbTJfcG9zLCBvdmVyYWxsX2F2ZXJhZ2VfTW9tM19wb3MsIG92ZXJhbGxfYXZlcmFnZV9Nb200X3Bvcywgb3ZlcmFsbF9hdmVyYWdlX01vbTVfcG9zLCBvdmVyYWxsX2F2ZXJhZ2VfTW9tNl9wb3MpKSkpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9Nb20xX3BvcywgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJyZWQiKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfTW9tMl9wb3MsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAiZ3JlZW4iKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfTW9tM19wb3MsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAieWVsbG93IikKbGluZXMob3ZlcmFsbF9hdmVyYWdlX01vbTRfcG9zLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gImJsdWUiKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfTW9tNV9wb3MsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAicHVycGxlIikKbGluZXMob3ZlcmFsbF9hdmVyYWdlX01vbTZfcG9zLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gIm9yYW5nZSIpCgojIEFkZCBsZWdlbmQKbGVnZW5kKCJib3R0b21sZWZ0IiwgbGVnZW5kID0gYygiTWFya2V0IE1ha2VyIiwgIk1vbTEiLCAiTW9tMiIsICJNb20zIiwgIk1vbTQiLCAiTW9tNSIsICJNb202IiksIGNvbCA9IGMoImJsYWNrIiwgInJlZCIsICJncmVlbiIsICJ5ZWxsb3ciLCAiYmx1ZSIsICJwdXJwbGUiLCAib3JhbmdlIiksIGx0eSA9IDEsIGNleCA9IDAuOCkKYGBgCgoKIyMgc2V0MTEgKDIgaW5mb3JtZWQgKyAyIG5vaXN5IGluZm9ybWVkICsgMiBub2lzeSkKCmBgYHtyfQojIEluaXRpYWxpemUgbWF0cmljZXMgdG8gc3RvcmUgYXZlcmFnZXMgZm9yIGVhY2ggcG9zaXRpb24KYXZlcmFnZV9iaWQgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfYXNrIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQoKIyBMb29wIHRocm91Z2ggZWFjaCBzaW11bGF0aW9uIChuKQpmb3IgKG4gaW4gMToxMCkgewogICMgRXh0cmFjdCBUcnVlIHZhbHVlcyBmcm9tIHRoZSBhZ2dyZWdhdGVkX3Jlc3VsdHNfNCBkYXRhZnJhbWUKICBCaWRzX3NldDExIDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c18xMVtuLCA0XSkpLCAiLCAiKQogIAogICMgRXh0cmFjdCBFeHBlY3RlZCB2YWx1ZXMgZnJvbSB0aGUgYWdncmVnYXRlZF9yZXN1bHRzXzQgZGF0YWZyYW1lCiAgQXNrc19zZXQxMSA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfMTFbbiwgNV0pKSwgIiwgIikKICAKICAjIExvb3AgdGhyb3VnaCBlYWNoIHBvc2l0aW9uIChpKQogIGZvciAoaSBpbiAxOjEwMCkgewogICAgIyBFeHRyYWN0IFRydWUgYW5kIEV4cGVjdGVkIHZhbHVlcyBmb3IgdGhlIGktdGggcG9zaXRpb24KICAgIEJpZHMgPC0gc2FwcGx5KEJpZHNfc2V0MTEsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICBBc2tzIDwtIHNhcHBseShBc2tzX3NldDExLCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgCiAgICAjIENhbGN1bGF0ZSB0aGUgYXZlcmFnZSBvZiBUcnVlIGFuZCBFeHBlY3RlZCB2YWx1ZXMgZm9yIHRoZSBpLXRoIHBvc2l0aW9uCiAgICBhdmVyYWdlX2JpZFtpLCBuXSA8LSBtZWFuKEJpZHMsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfYXNrW2ksIG5dIDwtIG1lYW4oQXNrcywgbmEucm0gPSBUUlVFKQogIH0KfQoKIyBDYWxjdWxhdGUgdGhlIG92ZXJhbGwgYXZlcmFnZSBmb3IgZWFjaCBwb3NpdGlvbiBhY3Jvc3MgYWxsIHNpbXVsYXRpb25zCm92ZXJhbGxfYXZlcmFnZV9iaWQgPC0gcm93TWVhbnMoYXZlcmFnZV9iaWQsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX2FzayA8LSByb3dNZWFucyhhdmVyYWdlX2FzaywgbmEucm0gPSBUUlVFKQoKIyMgVHJ1ZSBWYWx1ZQojIEluaXRpYWxpemUgbWF0cmljZXMgdG8gc3RvcmUgYXZlcmFnZXMgZm9yIGVhY2ggcG9zaXRpb24KYXZlcmFnZV90cnVlIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX2V4cGVjdGVkIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQoKIyBMb29wIHRocm91Z2ggZWFjaCBzaW11bGF0aW9uIChuKQpmb3IgKG4gaW4gMToxMCkgewogICMgRXh0cmFjdCBUcnVlIHZhbHVlcyBmcm9tIHRoZSBhZ2dyZWdhdGVkX3Jlc3VsdHNfNCBkYXRhZnJhbWUKICBUcnVlVmFsdWVzX3NldDExIDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c18xMVtuLCAyXSkpLCAiLCAiKQogIAogICMgRXh0cmFjdCBFeHBlY3RlZCB2YWx1ZXMgZnJvbSB0aGUgYWdncmVnYXRlZF9yZXN1bHRzXzQgZGF0YWZyYW1lCiAgRXhwZWN0ZWRWYWx1ZXNfc2V0MTEgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzExW24sIDNdKSksICIsICIpCiAgCiAgIyBMb29wIHRocm91Z2ggZWFjaCBwb3NpdGlvbiAoaSkKICBmb3IgKGkgaW4gMToxMDApIHsKICAgICMgRXh0cmFjdCBUcnVlIGFuZCBFeHBlY3RlZCB2YWx1ZXMgZm9yIHRoZSBpLXRoIHBvc2l0aW9uCiAgICBUcnVlX3ZhbHVlcyA8LSBzYXBwbHkoVHJ1ZVZhbHVlc19zZXQxMSwgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIEV4cGVjdGVkX3ZhbHVlcyA8LSBzYXBwbHkoRXhwZWN0ZWRWYWx1ZXNfc2V0MTEsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICAKICAgICMgQ2FsY3VsYXRlIHRoZSBhdmVyYWdlIG9mIFRydWUgYW5kIEV4cGVjdGVkIHZhbHVlcyBmb3IgdGhlIGktdGggcG9zaXRpb24KICAgIGF2ZXJhZ2VfdHJ1ZVtpLCBuXSA8LSBtZWFuKFRydWVfdmFsdWVzLCBuYS5ybSA9IFRSVUUpCiAgICBhdmVyYWdlX2V4cGVjdGVkW2ksIG5dIDwtIG1lYW4oRXhwZWN0ZWRfdmFsdWVzLCBuYS5ybSA9IFRSVUUpCiAgfQp9CgojIENhbGN1bGF0ZSB0aGUgb3ZlcmFsbCBhdmVyYWdlIGZvciBlYWNoIHBvc2l0aW9uIGFjcm9zcyBhbGwgc2ltdWxhdGlvbnMKb3ZlcmFsbF9hdmVyYWdlX3RydWUgPC0gcm93TWVhbnMoYXZlcmFnZV90cnVlLCBuYS5ybSA9IFRSVUUpCm92ZXJhbGxfYXZlcmFnZV9leHBlY3RlZCA8LSByb3dNZWFucyhhdmVyYWdlX2V4cGVjdGVkLCBuYS5ybSA9IFRSVUUpCgojIFBsb3QgdGhlIG92ZXJhbGwgYXZlcmFnZXMKI3Bsb3Qob3ZlcmFsbF9hdmVyYWdlX3RydWUsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAiYmx1ZSIsIG1haW4gPSAiT3ZlcmFsbCBBdmVyYWdlIG9mIFRydWUgdnMgRXhwZWN0ZWQgVmFsdWVzIiwgeGxhYiA9ICJQb3NpdGlvbiBpbiBMaXN0IiwgeWxhYiA9ICJWYWx1ZSIsIHlsaW0gPSBjKG1pbihjKG92ZXJhbGxfYXZlcmFnZV90cnVlLCBvdmVyYWxsX2F2ZXJhZ2VfZXhwZWN0ZWQpKSwgbWF4KGMob3ZlcmFsbF9hdmVyYWdlX3RydWUsIG92ZXJhbGxfYXZlcmFnZV9leHBlY3RlZCkpKSkKI2xpbmVzKG92ZXJhbGxfYXZlcmFnZV9leHBlY3RlZCwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJyZWQiKQojbGVnZW5kKCJ0b3ByaWdodCIsIGxlZ2VuZCA9IGMoIlRydWUgVmFsdWVzIiwgIkV4cGVjdGVkIFZhbHVlcyIpLCBjb2wgPSBjKCJibHVlIiwgInJlZCIpLCBsdHkgPSAxLCBjZXggPSAwLjgpCgojIFBsb3QgdGhlIG92ZXJhbGwgYXZlcmFnZXMKcGxvdChvdmVyYWxsX2F2ZXJhZ2VfYmlkLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gImJsdWUiLCBtYWluID0gIk92ZXJhbGwgQXZlcmFnZSBvZiBCaWRzIHZzIEFza3MgJiBUcnVlIHZzIEV4cGVjdGVkIFZhbHVlcyIsIHhsYWIgPSAiUG9zaXRpb24gaW4gTGlzdCIsIHlsYWIgPSAiVmFsdWUiLCB5bGltID0gYyhtaW4oYyhvdmVyYWxsX2F2ZXJhZ2VfYmlkLCBvdmVyYWxsX2F2ZXJhZ2VfYXNrLCBvdmVyYWxsX2F2ZXJhZ2VfdHJ1ZSwgb3ZlcmFsbF9hdmVyYWdlX2V4cGVjdGVkKSksIG1heChjKG92ZXJhbGxfYXZlcmFnZV9iaWQsIG92ZXJhbGxfYXZlcmFnZV9hc2ssIG92ZXJhbGxfYXZlcmFnZV90cnVlLCBvdmVyYWxsX2F2ZXJhZ2VfZXhwZWN0ZWQpKSkpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9hc2ssIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAicmVkIikKbGluZXMob3ZlcmFsbF9hdmVyYWdlX3RydWUsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAiZ3JlZW4iKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfZXhwZWN0ZWQsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAicHVycGxlIikKbGVnZW5kKCJib3R0b21sZWZ0IiwgbGVnZW5kID0gYygiQmlkcyIsICJBc2tzIiwgIlRydWUgVmFsdWUiLCAiRXhwZWN0ZWQgVmFsdWUiKSwgY29sID0gYygiYmx1ZSIsICJyZWQiLCAiZ3JlZW4iLCAicHVycGxlIiksIGx0eSA9IDEsIGNleCA9IDAuOCkKYGBgCgpgYGB7cn0KIyBJbml0aWFsaXplIG1hdHJpY2VzIHRvIHN0b3JlIGF2ZXJhZ2VzIGZvciBlYWNoIHBvc2l0aW9uCmF2ZXJhZ2VfTU1fcG5sIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX0luZm9ybWVkMV9wbmwgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfSW5mb3JtZWQyX3BubCA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKYXZlcmFnZV9Ob2lzeUluZm9ybWVkMV9wbmwgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfTm9pc3lJbmZvcm1lZDJfcG5sIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX05vaXN5MV9wbmwgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfTm9pc3kyX3BubCA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKCiMgTG9vcCB0aHJvdWdoIGVhY2ggc2ltdWxhdGlvbiAobikKZm9yIChuIGluIDE6MTApIHsKCiAgTU1fcG5sX3NldDExIDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c18xMVtuLCA2XSkpLCAiLCAiKQoKICBJbmZvcm1lZDFfcG5sX3NldDExIDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c18xMVtuLCA4XSkpLCAiLCAiKQogIAogIEluZm9ybWVkMl9wbmxfc2V0MTEgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzExW24sIDEwXSkpLCAiLCAiKQogIAogIE5vaXN5SW5mb3JtZWQxX3BubF9zZXQxMSA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfMTFbbiwgMTJdKSksICIsICIpCiAgCiAgTm9pc3lJbmZvcm1lZDJfcG5sX3NldDExIDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c18xMVtuLCAxNF0pKSwgIiwgIikKICAKICBOb2lzeTFfcG5sX3NldDExIDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c18xMVtuLCAxNl0pKSwgIiwgIikKICAKICBOb2lzeTJfcG5sX3NldDExIDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c18xMVtuLCAxOF0pKSwgIiwgIikKICAKICAjIExvb3AgdGhyb3VnaCBlYWNoIHBvc2l0aW9uIChpKQogIGZvciAoaSBpbiAxOjEwMCkgewogICAgIyBFeHRyYWN0IFRydWUgYW5kIEV4cGVjdGVkIHZhbHVlcyBmb3IgdGhlIGktdGggcG9zaXRpb24KICAgIE1NX3BubCA8LSBzYXBwbHkoTU1fcG5sX3NldDExLCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgSW5mb3JtZWQxX3BubCA8LSBzYXBwbHkoSW5mb3JtZWQxX3BubF9zZXQxMSwgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIEluZm9ybWVkMl9wbmwgPC0gc2FwcGx5KEluZm9ybWVkMl9wbmxfc2V0MTEsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICBOb2lzeUluZm9ybWVkMV9wbmwgPC0gc2FwcGx5KE5vaXN5SW5mb3JtZWQxX3BubF9zZXQxMSwgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIE5vaXN5SW5mb3JtZWQxX3BubCA8LSBzYXBwbHkoTm9pc3lJbmZvcm1lZDJfcG5sX3NldDExLCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgTm9pc3kxX3BubCA8LSBzYXBwbHkoTm9pc3kxX3BubF9zZXQxMSwgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIE5vaXN5Ml9wbmwgPC0gc2FwcGx5KE5vaXN5Ml9wbmxfc2V0MTEsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICAKICAgICMgQ2FsY3VsYXRlIHRoZSBhdmVyYWdlIG9mIFRydWUgYW5kIEV4cGVjdGVkIHZhbHVlcyBmb3IgdGhlIGktdGggcG9zaXRpb24KICAgIGF2ZXJhZ2VfTU1fcG5sW2ksIG5dIDwtIG1lYW4oTU1fcG5sLCBuYS5ybSA9IFRSVUUpCiAgICBhdmVyYWdlX0luZm9ybWVkMV9wbmxbaSwgbl0gPC0gbWVhbihJbmZvcm1lZDFfcG5sLCBuYS5ybSA9IFRSVUUpCiAgICBhdmVyYWdlX0luZm9ybWVkMl9wbmxbaSwgbl0gPC0gbWVhbihJbmZvcm1lZDJfcG5sLCBuYS5ybSA9IFRSVUUpCiAgICBhdmVyYWdlX05vaXN5SW5mb3JtZWQxX3BubFtpLCBuXSA8LSBtZWFuKE5vaXN5SW5mb3JtZWQxX3BubCwgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9Ob2lzeUluZm9ybWVkMl9wbmxbaSwgbl0gPC0gbWVhbihOb2lzeUluZm9ybWVkMl9wbmwsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfTm9pc3kxX3BubFtpLCBuXSA8LSBtZWFuKE5vaXN5MV9wbmwsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfTm9pc3kyX3BubFtpLCBuXSA8LSBtZWFuKE5vaXN5Ml9wbmwsIG5hLnJtID0gVFJVRSkKICB9Cn0KCiMgQ2FsY3VsYXRlIHRoZSBvdmVyYWxsIGF2ZXJhZ2UgZm9yIGVhY2ggcG9zaXRpb24gYWNyb3NzIGFsbCBzaW11bGF0aW9ucwpvdmVyYWxsX2F2ZXJhZ2VfTU1fcG5sIDwtIHJvd01lYW5zKGF2ZXJhZ2VfTU1fcG5sLCBuYS5ybSA9IFRSVUUpCm92ZXJhbGxfYXZlcmFnZV9JbmZvcm1lZDFfcG5sIDwtIHJvd01lYW5zKGF2ZXJhZ2VfSW5mb3JtZWQxX3BubCwgbmEucm0gPSBUUlVFKQpvdmVyYWxsX2F2ZXJhZ2VfSW5mb3JtZWQyX3BubCA8LSByb3dNZWFucyhhdmVyYWdlX0luZm9ybWVkMl9wbmwsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX05vaXN5SW5mb3JtZWQxX3BubCA8LSByb3dNZWFucyhhdmVyYWdlX05vaXN5SW5mb3JtZWQxX3BubCwgbmEucm0gPSBUUlVFKQpvdmVyYWxsX2F2ZXJhZ2VfTm9pc3lJbmZvcm1lZDJfcG5sIDwtIHJvd01lYW5zKGF2ZXJhZ2VfTm9pc3lJbmZvcm1lZDJfcG5sLCBuYS5ybSA9IFRSVUUpCm92ZXJhbGxfYXZlcmFnZV9Ob2lzeTFfcG5sIDwtIHJvd01lYW5zKGF2ZXJhZ2VfTm9pc3kxX3BubCwgbmEucm0gPSBUUlVFKQpvdmVyYWxsX2F2ZXJhZ2VfTm9pc3kyX3BubCA8LSByb3dNZWFucyhhdmVyYWdlX05vaXN5Ml9wbmwsIG5hLnJtID0gVFJVRSkKCiMgUGxvdCB0aGUgb3ZlcmFsbCBhdmVyYWdlcwpwbG90KG92ZXJhbGxfYXZlcmFnZV9NTV9wbmwsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAiYmxhY2siLCBtYWluID0gIk92ZXJhbGwgQXZlcmFnZSBQTkwiLCB4bGFiID0gIlBvc2l0aW9uIGluIExpc3QiLCB5bGFiID0gIlZhbHVlIiwgeWxpbSA9IGMobWluKGMob3ZlcmFsbF9hdmVyYWdlX01NX3BubCwgb3ZlcmFsbF9hdmVyYWdlX0luZm9ybWVkMV9wbmwsIG92ZXJhbGxfYXZlcmFnZV9JbmZvcm1lZDJfcG5sLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3lJbmZvcm1lZDFfcG5sLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3lJbmZvcm1lZDJfcG5sLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3kxX3BubCwgb3ZlcmFsbF9hdmVyYWdlX05vaXN5Ml9wbmwpKSwgbWF4KGMob3ZlcmFsbF9hdmVyYWdlX01NX3BubCwgb3ZlcmFsbF9hdmVyYWdlX0luZm9ybWVkMV9wbmwsIG92ZXJhbGxfYXZlcmFnZV9JbmZvcm1lZDJfcG5sLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3lJbmZvcm1lZDFfcG5sLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3lJbmZvcm1lZDJfcG5sLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3kxX3BubCwgb3ZlcmFsbF9hdmVyYWdlX05vaXN5Ml9wbmwpKSkpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9JbmZvcm1lZDFfcG5sLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gInJlZCIpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9JbmZvcm1lZDJfcG5sLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gImdyZWVuIikKbGluZXMob3ZlcmFsbF9hdmVyYWdlX05vaXN5SW5mb3JtZWQxX3BubCwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJ5ZWxsb3ciKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfTm9pc3lJbmZvcm1lZDJfcG5sLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gImJsdWUiKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfTm9pc3kxX3BubCwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJwdXJwbGUiKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfTm9pc3kyX3BubCwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJvcmFuZ2UiKQoKIyBBZGQgbGVnZW5kCmxlZ2VuZCgiYm90dG9tbGVmdCIsIGxlZ2VuZCA9IGMoIk1hcmtldCBNYWtlciIsICJJbmZvcm1lZCAxIiwgIkluZm9ybWVkIDIiLCAiTm9pc3kgSW5mb3JtZWQgMSIsICJOb2lzeSBJbmZvcm1lZCAyIiwgIk5vaXN5IDEiLCAiTm9pc3kgMiIpLCBjb2wgPSBjKCJibGFjayIsICJyZWQiLCAiZ3JlZW4iLCAieWVsbG93IiwgImJsdWUiLCAicHVycGxlIiwgIm9yYW5nZSIpLCBsdHkgPSAxLCBjZXggPSAwLjgpCmBgYAoKYGBge3J9CiMgSW5pdGlhbGl6ZSBtYXRyaWNlcyB0byBzdG9yZSBhdmVyYWdlcyBmb3IgZWFjaCBwb3NpdGlvbgphdmVyYWdlX01NX3BvcyA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKYXZlcmFnZV9JbmZvcm1lZDFfcG9zIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX0luZm9ybWVkMl9wb3MgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfTm9pc3lJbmZvcm1lZDFfcG9zIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX05vaXN5SW5mb3JtZWQyX3BvcyA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKYXZlcmFnZV9Ob2lzeTFfcG9zIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX05vaXN5Ml9wb3MgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCgojIExvb3AgdGhyb3VnaCBlYWNoIHNpbXVsYXRpb24gKG4pCmZvciAobiBpbiAxOjEwKSB7CgogIE1NX3Bvc19zZXQxMSA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfMTFbbiwgN10pKSwgIiwgIikKCiAgSW5mb3JtZWQxX3Bvc19zZXQxMSA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfMTFbbiwgOV0pKSwgIiwgIikKICAKICBJbmZvcm1lZDJfcG9zX3NldDExIDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c18xMVtuLCAxMV0pKSwgIiwgIikKICAKICBOb2lzeUluZm9ybWVkMV9wb3Nfc2V0MTEgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzExW24sIDEzXSkpLCAiLCAiKQogIAogIE5vaXN5SW5mb3JtZWQyX3Bvc19zZXQxMSA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfMTFbbiwgMTVdKSksICIsICIpCiAgCiAgTm9pc3kxX3Bvc19zZXQxMSA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfMTFbbiwgMTddKSksICIsICIpCiAgCiAgTm9pc3kyX3Bvc19zZXQxMSA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfMTFbbiwgMTldKSksICIsICIpCiAgCiAgIyBMb29wIHRocm91Z2ggZWFjaCBwb3NpdGlvbiAoaSkKICBmb3IgKGkgaW4gMToxMDApIHsKICAgICMgRXh0cmFjdCBUcnVlIGFuZCBFeHBlY3RlZCB2YWx1ZXMgZm9yIHRoZSBpLXRoIHBvc2l0aW9uCiAgICBNTV9wb3MgPC0gc2FwcGx5KE1NX3BubF9zZXQxMSwgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIEluZm9ybWVkMV9wb3MgPC0gc2FwcGx5KEluZm9ybWVkMV9wb3Nfc2V0MTEsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICBJbmZvcm1lZDJfcG9zIDwtIHNhcHBseShJbmZvcm1lZDJfcG9zX3NldDExLCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgTm9pc3lJbmZvcm1lZDFfcG9zIDwtIHNhcHBseShOb2lzeUluZm9ybWVkMV9wb3Nfc2V0MTEsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICBOb2lzeUluZm9ybWVkMV9wb3MgPC0gc2FwcGx5KE5vaXN5SW5mb3JtZWQyX3Bvc19zZXQxMSwgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIE5vaXN5MV9wb3MgPC0gc2FwcGx5KE5vaXN5MV9wb3Nfc2V0MTEsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICBOb2lzeTJfcG9zIDwtIHNhcHBseShOb2lzeTJfcG9zX3NldDExLCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgCiAgICAjIENhbGN1bGF0ZSB0aGUgYXZlcmFnZSBvZiBUcnVlIGFuZCBFeHBlY3RlZCB2YWx1ZXMgZm9yIHRoZSBpLXRoIHBvc2l0aW9uCiAgICBhdmVyYWdlX01NX3Bvc1tpLCBuXSA8LSBtZWFuKE1NX3BvcywgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9JbmZvcm1lZDFfcG9zW2ksIG5dIDwtIG1lYW4oSW5mb3JtZWQxX3BvcywgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9JbmZvcm1lZDJfcG9zW2ksIG5dIDwtIG1lYW4oSW5mb3JtZWQyX3BvcywgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9Ob2lzeUluZm9ybWVkMV9wb3NbaSwgbl0gPC0gbWVhbihOb2lzeUluZm9ybWVkMV9wb3MsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfTm9pc3lJbmZvcm1lZDJfcG9zW2ksIG5dIDwtIG1lYW4oTm9pc3lJbmZvcm1lZDJfcG9zLCBuYS5ybSA9IFRSVUUpCiAgICBhdmVyYWdlX05vaXN5MV9wb3NbaSwgbl0gPC0gbWVhbihOb2lzeTFfcG9zLCBuYS5ybSA9IFRSVUUpCiAgICBhdmVyYWdlX05vaXN5Ml9wb3NbaSwgbl0gPC0gbWVhbihOb2lzeTJfcG9zLCBuYS5ybSA9IFRSVUUpCiAgfQp9CgojIENhbGN1bGF0ZSB0aGUgb3ZlcmFsbCBhdmVyYWdlIGZvciBlYWNoIHBvc2l0aW9uIGFjcm9zcyBhbGwgc2ltdWxhdGlvbnMKb3ZlcmFsbF9hdmVyYWdlX01NX3BvcyA8LSByb3dNZWFucyhhdmVyYWdlX01NX3BvcywgbmEucm0gPSBUUlVFKQpvdmVyYWxsX2F2ZXJhZ2VfSW5mb3JtZWQxX3BvcyA8LSByb3dNZWFucyhhdmVyYWdlX0luZm9ybWVkMV9wb3MsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX0luZm9ybWVkMl9wb3MgPC0gcm93TWVhbnMoYXZlcmFnZV9JbmZvcm1lZDJfcG9zLCBuYS5ybSA9IFRSVUUpCm92ZXJhbGxfYXZlcmFnZV9Ob2lzeUluZm9ybWVkMV9wb3MgPC0gcm93TWVhbnMoYXZlcmFnZV9Ob2lzeUluZm9ybWVkMV9wb3MsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX05vaXN5SW5mb3JtZWQyX3BvcyA8LSByb3dNZWFucyhhdmVyYWdlX05vaXN5SW5mb3JtZWQyX3BvcywgbmEucm0gPSBUUlVFKQpvdmVyYWxsX2F2ZXJhZ2VfTm9pc3kxX3BvcyA8LSByb3dNZWFucyhhdmVyYWdlX05vaXN5MV9wb3MsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX05vaXN5Ml9wb3MgPC0gcm93TWVhbnMoYXZlcmFnZV9Ob2lzeTJfcG9zLCBuYS5ybSA9IFRSVUUpCgojIFBsb3QgdGhlIG92ZXJhbGwgYXZlcmFnZXMKcGxvdChvdmVyYWxsX2F2ZXJhZ2VfTU1fcG9zLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gImJsYWNrIiwgbWFpbiA9ICJPdmVyYWxsIEF2ZXJhZ2UgUG9zaXRpb24iLCB4bGFiID0gIlBvc2l0aW9uIGluIExpc3QiLCB5bGFiID0gIlZhbHVlIiwgeWxpbSA9IGMobWluKGMob3ZlcmFsbF9hdmVyYWdlX01NX3Bvcywgb3ZlcmFsbF9hdmVyYWdlX0luZm9ybWVkMV9wb3MsIG92ZXJhbGxfYXZlcmFnZV9JbmZvcm1lZDJfcG9zLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3lJbmZvcm1lZDFfcG9zLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3lJbmZvcm1lZDJfcG9zLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3kxX3Bvcywgb3ZlcmFsbF9hdmVyYWdlX05vaXN5Ml9wb3MpKSwgbWF4KGMob3ZlcmFsbF9hdmVyYWdlX01NX3Bvcywgb3ZlcmFsbF9hdmVyYWdlX0luZm9ybWVkMV9wb3MsIG92ZXJhbGxfYXZlcmFnZV9JbmZvcm1lZDJfcG9zLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3lJbmZvcm1lZDFfcG9zLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3lJbmZvcm1lZDJfcG9zLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3kxX3Bvcywgb3ZlcmFsbF9hdmVyYWdlX05vaXN5Ml9wb3MpKSkpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9JbmZvcm1lZDFfcG9zLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gInJlZCIpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9JbmZvcm1lZDJfcG9zLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gImdyZWVuIikKbGluZXMob3ZlcmFsbF9hdmVyYWdlX05vaXN5SW5mb3JtZWQxX3BvcywgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJ5ZWxsb3ciKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfTm9pc3lJbmZvcm1lZDJfcG9zLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gImJsdWUiKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfTm9pc3kxX3BvcywgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJwdXJwbGUiKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfTm9pc3kyX3BvcywgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJvcmFuZ2UiKQoKIyBBZGQgbGVnZW5kCmxlZ2VuZCgiYm90dG9tbGVmdCIsIGxlZ2VuZCA9IGMoIk1hcmtldCBNYWtlciIsICJJbmZvcm1lZCAxIiwgIkluZm9ybWVkIDIiLCAiTm9pc3kgSW5mb3JtZWQgMSIsICJOb2lzeSBJbmZvcm1lZCAyIiwgIk5vaXN5IDEiLCAiTm9pc3kgMiIpLCBjb2wgPSBjKCJibGFjayIsICJyZWQiLCAiZ3JlZW4iLCAieWVsbG93IiwgImJsdWUiLCAicHVycGxlIiwgIm9yYW5nZSIpLCBsdHkgPSAxLCBjZXggPSAwLjgpCmBgYAoKCgojIyBzZXQxMiAoNiBTdG9jaGFzdGljIE5vaXN5KQoKYGBge3J9CiMgSW5pdGlhbGl6ZSBtYXRyaWNlcyB0byBzdG9yZSBhdmVyYWdlcyBmb3IgZWFjaCBwb3NpdGlvbgphdmVyYWdlX2JpZCA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKYXZlcmFnZV9hc2sgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCgojIExvb3AgdGhyb3VnaCBlYWNoIHNpbXVsYXRpb24gKG4pCmZvciAobiBpbiAxOjEwKSB7CiAgIyBFeHRyYWN0IFRydWUgdmFsdWVzIGZyb20gdGhlIGFnZ3JlZ2F0ZWRfcmVzdWx0c180IGRhdGFmcmFtZQogIEJpZHNfc2V0MTIgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzEyW24sIDRdKSksICIsICIpCiAgCiAgIyBFeHRyYWN0IEV4cGVjdGVkIHZhbHVlcyBmcm9tIHRoZSBhZ2dyZWdhdGVkX3Jlc3VsdHNfNCBkYXRhZnJhbWUKICBBc2tzX3NldDEyIDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c18xMltuLCA1XSkpLCAiLCAiKQogIAogICMgTG9vcCB0aHJvdWdoIGVhY2ggcG9zaXRpb24gKGkpCiAgZm9yIChpIGluIDE6MTAwKSB7CiAgICAjIEV4dHJhY3QgVHJ1ZSBhbmQgRXhwZWN0ZWQgdmFsdWVzIGZvciB0aGUgaS10aCBwb3NpdGlvbgogICAgQmlkcyA8LSBzYXBwbHkoQmlkc19zZXQxMiwgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIEFza3MgPC0gc2FwcGx5KEFza3Nfc2V0MTIsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICAKICAgICMgQ2FsY3VsYXRlIHRoZSBhdmVyYWdlIG9mIFRydWUgYW5kIEV4cGVjdGVkIHZhbHVlcyBmb3IgdGhlIGktdGggcG9zaXRpb24KICAgIGF2ZXJhZ2VfYmlkW2ksIG5dIDwtIG1lYW4oQmlkcywgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9hc2tbaSwgbl0gPC0gbWVhbihBc2tzLCBuYS5ybSA9IFRSVUUpCiAgfQp9CgojIENhbGN1bGF0ZSB0aGUgb3ZlcmFsbCBhdmVyYWdlIGZvciBlYWNoIHBvc2l0aW9uIGFjcm9zcyBhbGwgc2ltdWxhdGlvbnMKb3ZlcmFsbF9hdmVyYWdlX2JpZCA8LSByb3dNZWFucyhhdmVyYWdlX2JpZCwgbmEucm0gPSBUUlVFKQpvdmVyYWxsX2F2ZXJhZ2VfYXNrIDwtIHJvd01lYW5zKGF2ZXJhZ2VfYXNrLCBuYS5ybSA9IFRSVUUpCgojIyBUcnVlIFZhbHVlCiMgSW5pdGlhbGl6ZSBtYXRyaWNlcyB0byBzdG9yZSBhdmVyYWdlcyBmb3IgZWFjaCBwb3NpdGlvbgphdmVyYWdlX3RydWUgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfZXhwZWN0ZWQgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCgojIExvb3AgdGhyb3VnaCBlYWNoIHNpbXVsYXRpb24gKG4pCmZvciAobiBpbiAxOjEwKSB7CiAgIyBFeHRyYWN0IFRydWUgdmFsdWVzIGZyb20gdGhlIGFnZ3JlZ2F0ZWRfcmVzdWx0c180IGRhdGFmcmFtZQogIFRydWVWYWx1ZXNfc2V0MTIgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzEyW24sIDJdKSksICIsICIpCiAgCiAgIyBFeHRyYWN0IEV4cGVjdGVkIHZhbHVlcyBmcm9tIHRoZSBhZ2dyZWdhdGVkX3Jlc3VsdHNfNCBkYXRhZnJhbWUKICBFeHBlY3RlZFZhbHVlc19zZXQxMiA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfMTJbbiwgM10pKSwgIiwgIikKICAKICAjIExvb3AgdGhyb3VnaCBlYWNoIHBvc2l0aW9uIChpKQogIGZvciAoaSBpbiAxOjEwMCkgewogICAgIyBFeHRyYWN0IFRydWUgYW5kIEV4cGVjdGVkIHZhbHVlcyBmb3IgdGhlIGktdGggcG9zaXRpb24KICAgIFRydWVfdmFsdWVzIDwtIHNhcHBseShUcnVlVmFsdWVzX3NldDEyLCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgRXhwZWN0ZWRfdmFsdWVzIDwtIHNhcHBseShFeHBlY3RlZFZhbHVlc19zZXQxMiwgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIAogICAgIyBDYWxjdWxhdGUgdGhlIGF2ZXJhZ2Ugb2YgVHJ1ZSBhbmQgRXhwZWN0ZWQgdmFsdWVzIGZvciB0aGUgaS10aCBwb3NpdGlvbgogICAgYXZlcmFnZV90cnVlW2ksIG5dIDwtIG1lYW4oVHJ1ZV92YWx1ZXMsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfZXhwZWN0ZWRbaSwgbl0gPC0gbWVhbihFeHBlY3RlZF92YWx1ZXMsIG5hLnJtID0gVFJVRSkKICB9Cn0KCiMgQ2FsY3VsYXRlIHRoZSBvdmVyYWxsIGF2ZXJhZ2UgZm9yIGVhY2ggcG9zaXRpb24gYWNyb3NzIGFsbCBzaW11bGF0aW9ucwpvdmVyYWxsX2F2ZXJhZ2VfdHJ1ZSA8LSByb3dNZWFucyhhdmVyYWdlX3RydWUsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX2V4cGVjdGVkIDwtIHJvd01lYW5zKGF2ZXJhZ2VfZXhwZWN0ZWQsIG5hLnJtID0gVFJVRSkKCiMgUGxvdCB0aGUgb3ZlcmFsbCBhdmVyYWdlcwojcGxvdChvdmVyYWxsX2F2ZXJhZ2VfdHJ1ZSwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJibHVlIiwgbWFpbiA9ICJPdmVyYWxsIEF2ZXJhZ2Ugb2YgVHJ1ZSB2cyBFeHBlY3RlZCBWYWx1ZXMiLCB4bGFiID0gIlBvc2l0aW9uIGluIExpc3QiLCB5bGFiID0gIlZhbHVlIiwgeWxpbSA9IGMobWluKGMob3ZlcmFsbF9hdmVyYWdlX3RydWUsIG92ZXJhbGxfYXZlcmFnZV9leHBlY3RlZCkpLCBtYXgoYyhvdmVyYWxsX2F2ZXJhZ2VfdHJ1ZSwgb3ZlcmFsbF9hdmVyYWdlX2V4cGVjdGVkKSkpKQojbGluZXMob3ZlcmFsbF9hdmVyYWdlX2V4cGVjdGVkLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gInJlZCIpCiNsZWdlbmQoInRvcHJpZ2h0IiwgbGVnZW5kID0gYygiVHJ1ZSBWYWx1ZXMiLCAiRXhwZWN0ZWQgVmFsdWVzIiksIGNvbCA9IGMoImJsdWUiLCAicmVkIiksIGx0eSA9IDEsIGNleCA9IDAuOCkKCiMgUGxvdCB0aGUgb3ZlcmFsbCBhdmVyYWdlcwpwbG90KG92ZXJhbGxfYXZlcmFnZV9iaWQsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAiYmx1ZSIsIG1haW4gPSAiT3ZlcmFsbCBBdmVyYWdlIG9mIEJpZHMgdnMgQXNrcyAmIFRydWUgdnMgRXhwZWN0ZWQgVmFsdWVzIiwgeGxhYiA9ICJQb3NpdGlvbiBpbiBMaXN0IiwgeWxhYiA9ICJWYWx1ZSIsIHlsaW0gPSBjKG1pbihjKG92ZXJhbGxfYXZlcmFnZV9iaWQsIG92ZXJhbGxfYXZlcmFnZV9hc2ssIG92ZXJhbGxfYXZlcmFnZV90cnVlLCBvdmVyYWxsX2F2ZXJhZ2VfZXhwZWN0ZWQpKSwgbWF4KGMob3ZlcmFsbF9hdmVyYWdlX2JpZCwgb3ZlcmFsbF9hdmVyYWdlX2Fzaywgb3ZlcmFsbF9hdmVyYWdlX3RydWUsIG92ZXJhbGxfYXZlcmFnZV9leHBlY3RlZCkpKSkKbGluZXMob3ZlcmFsbF9hdmVyYWdlX2FzaywgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJyZWQiKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfdHJ1ZSwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJncmVlbiIpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9leHBlY3RlZCwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJwdXJwbGUiKQpsZWdlbmQoImJvdHRvbWxlZnQiLCBsZWdlbmQgPSBjKCJCaWRzIiwgIkFza3MiLCAiVHJ1ZSBWYWx1ZSIsICJFeHBlY3RlZCBWYWx1ZSIpLCBjb2wgPSBjKCJibHVlIiwgInJlZCIsICJncmVlbiIsICJwdXJwbGUiKSwgbHR5ID0gMSwgY2V4ID0gMC44KQpgYGAKCmBgYHtyfQojIEluaXRpYWxpemUgbWF0cmljZXMgdG8gc3RvcmUgYXZlcmFnZXMgZm9yIGVhY2ggcG9zaXRpb24KYXZlcmFnZV9NTV9wbmwgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfU3RvY2hOb2lzeTFfcG5sIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX1N0b2NoTm9pc3kyX3BubCA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKYXZlcmFnZV9TdG9jaE5vaXN5M19wbmwgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfU3RvY2hOb2lzeTRfcG5sIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX1N0b2NoTm9pc3k1X3BubCA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKYXZlcmFnZV9TdG9jaE5vaXN5Nl9wbmwgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCgojIExvb3AgdGhyb3VnaCBlYWNoIHNpbXVsYXRpb24gKG4pCmZvciAobiBpbiAxOjEwKSB7CgogIE1NX3BubF9zZXQxMiA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfMTJbbiwgNl0pKSwgIiwgIikKCiAgU3RvY2hOb2lzeTFfcG5sX3NldDEyIDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c18xMltuLCA4XSkpLCAiLCAiKQogIAogIFN0b2NoTm9pc3kyX3BubF9zZXQxMiA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfMTJbbiwgMTBdKSksICIsICIpCiAgCiAgU3RvY2hOb2lzeTNfcG5sX3NldDEyIDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c18xMltuLCAxMl0pKSwgIiwgIikKICAKICBTdG9jaE5vaXN5NF9wbmxfc2V0MTIgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzEyW24sIDE0XSkpLCAiLCAiKQogIAogIFN0b2NoTm9pc3k1X3BubF9zZXQxMiA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfMTJbbiwgMTZdKSksICIsICIpCiAgCiAgU3RvY2hOb2lzeTZfcG5sX3NldDEyIDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c18xMltuLCAxOF0pKSwgIiwgIikKICAKICAjIExvb3AgdGhyb3VnaCBlYWNoIHBvc2l0aW9uIChpKQogIGZvciAoaSBpbiAxOjEwMCkgewogICAgIyBFeHRyYWN0IFRydWUgYW5kIEV4cGVjdGVkIHZhbHVlcyBmb3IgdGhlIGktdGggcG9zaXRpb24KICAgIE1NX3BubCA8LSBzYXBwbHkoTU1fcG5sX3NldDEyLCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgU3RvY2hOb2lzeTFfcG5sIDwtIHNhcHBseShTdG9jaE5vaXN5MV9wbmxfc2V0MTIsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICBTdG9jaE5vaXN5Ml9wbmwgPC0gc2FwcGx5KFN0b2NoTm9pc3kyX3BubF9zZXQxMiwgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIFN0b2NoTm9pc3kzX3BubCA8LSBzYXBwbHkoU3RvY2hOb2lzeTNfcG5sX3NldDEyLCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgU3RvY2hOb2lzeTRfcG5sIDwtIHNhcHBseShTdG9jaE5vaXN5NF9wbmxfc2V0MTIsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICBTdG9jaE5vaXN5NV9wbmwgPC0gc2FwcGx5KFN0b2NoTm9pc3k1X3BubF9zZXQxMiwgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIFN0b2NoTm9pc3k2X3BubCA8LSBzYXBwbHkoU3RvY2hOb2lzeTZfcG5sX3NldDEyLCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgCiAgICAjIENhbGN1bGF0ZSB0aGUgYXZlcmFnZSBvZiBUcnVlIGFuZCBFeHBlY3RlZCB2YWx1ZXMgZm9yIHRoZSBpLXRoIHBvc2l0aW9uCiAgICBhdmVyYWdlX01NX3BubFtpLCBuXSA8LSBtZWFuKE1NX3BubCwgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9TdG9jaE5vaXN5MV9wbmxbaSwgbl0gPC0gbWVhbihTdG9jaE5vaXN5MV9wbmwsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfU3RvY2hOb2lzeTJfcG5sW2ksIG5dIDwtIG1lYW4oU3RvY2hOb2lzeTJfcG5sLCBuYS5ybSA9IFRSVUUpCiAgICBhdmVyYWdlX1N0b2NoTm9pc3kzX3BubFtpLCBuXSA8LSBtZWFuKFN0b2NoTm9pc3kzX3BubCwgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9TdG9jaE5vaXN5NF9wbmxbaSwgbl0gPC0gbWVhbihTdG9jaE5vaXN5NF9wbmwsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfU3RvY2hOb2lzeTVfcG5sW2ksIG5dIDwtIG1lYW4oU3RvY2hOb2lzeTVfcG5sLCBuYS5ybSA9IFRSVUUpCiAgICBhdmVyYWdlX1N0b2NoTm9pc3k2X3BubFtpLCBuXSA8LSBtZWFuKFN0b2NoTm9pc3k2X3BubCwgbmEucm0gPSBUUlVFKQogIH0KfQoKIyBDYWxjdWxhdGUgdGhlIG92ZXJhbGwgYXZlcmFnZSBmb3IgZWFjaCBwb3NpdGlvbiBhY3Jvc3MgYWxsIHNpbXVsYXRpb25zCm92ZXJhbGxfYXZlcmFnZV9NTV9wbmwgPC0gcm93TWVhbnMoYXZlcmFnZV9NTV9wbmwsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX1N0b2NoTm9pc3kxX3BubCA8LSByb3dNZWFucyhhdmVyYWdlX1N0b2NoTm9pc3kxX3BubCwgbmEucm0gPSBUUlVFKQpvdmVyYWxsX2F2ZXJhZ2VfU3RvY2hOb2lzeTJfcG5sIDwtIHJvd01lYW5zKGF2ZXJhZ2VfU3RvY2hOb2lzeTJfcG5sLCBuYS5ybSA9IFRSVUUpCm92ZXJhbGxfYXZlcmFnZV9TdG9jaE5vaXN5M19wbmwgPC0gcm93TWVhbnMoYXZlcmFnZV9TdG9jaE5vaXN5M19wbmwsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX1N0b2NoTm9pc3k0X3BubCA8LSByb3dNZWFucyhhdmVyYWdlX1N0b2NoTm9pc3k0X3BubCwgbmEucm0gPSBUUlVFKQpvdmVyYWxsX2F2ZXJhZ2VfU3RvY2hOb2lzeTVfcG5sIDwtIHJvd01lYW5zKGF2ZXJhZ2VfU3RvY2hOb2lzeTVfcG5sLCBuYS5ybSA9IFRSVUUpCm92ZXJhbGxfYXZlcmFnZV9TdG9jaE5vaXN5Nl9wbmwgPC0gcm93TWVhbnMoYXZlcmFnZV9TdG9jaE5vaXN5Nl9wbmwsIG5hLnJtID0gVFJVRSkKCiMgUGxvdCB0aGUgb3ZlcmFsbCBhdmVyYWdlcwpwbG90KG92ZXJhbGxfYXZlcmFnZV9NTV9wbmwsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAiYmxhY2siLCBtYWluID0gIk92ZXJhbGwgQXZlcmFnZSBQTkwiLCB4bGFiID0gIlBvc2l0aW9uIGluIExpc3QiLCB5bGFiID0gIlZhbHVlIiwgeWxpbSA9IGMobWluKGMob3ZlcmFsbF9hdmVyYWdlX01NX3BubCwgb3ZlcmFsbF9hdmVyYWdlX1N0b2NoTm9pc3kxX3BubCwgb3ZlcmFsbF9hdmVyYWdlX1N0b2NoTm9pc3kyX3BubCwgb3ZlcmFsbF9hdmVyYWdlX1N0b2NoTm9pc3kzX3BubCwgb3ZlcmFsbF9hdmVyYWdlX1N0b2NoTm9pc3k0X3BubCwgb3ZlcmFsbF9hdmVyYWdlX1N0b2NoTm9pc3k1X3BubCwgb3ZlcmFsbF9hdmVyYWdlX1N0b2NoTm9pc3k2X3BubCkpLCBtYXgoYyhvdmVyYWxsX2F2ZXJhZ2VfTU1fcG5sLCBvdmVyYWxsX2F2ZXJhZ2VfU3RvY2hOb2lzeTFfcG5sLCBvdmVyYWxsX2F2ZXJhZ2VfU3RvY2hOb2lzeTJfcG5sLCBvdmVyYWxsX2F2ZXJhZ2VfU3RvY2hOb2lzeTNfcG5sLCBvdmVyYWxsX2F2ZXJhZ2VfU3RvY2hOb2lzeTRfcG5sLCBvdmVyYWxsX2F2ZXJhZ2VfU3RvY2hOb2lzeTVfcG5sLCBvdmVyYWxsX2F2ZXJhZ2VfU3RvY2hOb2lzeTZfcG5sKSkpKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfU3RvY2hOb2lzeTFfcG5sLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gInJlZCIpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9TdG9jaE5vaXN5Ml9wbmwsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAiZ3JlZW4iKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfU3RvY2hOb2lzeTNfcG5sLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gInllbGxvdyIpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9TdG9jaE5vaXN5NF9wbmwsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAiYmx1ZSIpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9TdG9jaE5vaXN5NV9wbmwsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAicHVycGxlIikKbGluZXMob3ZlcmFsbF9hdmVyYWdlX1N0b2NoTm9pc3k2X3BubCwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJvcmFuZ2UiKQoKIyBBZGQgbGVnZW5kCmxlZ2VuZCgidG9wbGVmdCIsIGxlZ2VuZCA9IGMoIk1hcmtldCBNYWtlciIsICJTdG9jaGFjdGljIE5vaXN5IDEiLCAiU3RvY2hhY3RpYyBOb2lzeSAyIiwgIlN0b2NoYWN0aWMgTm9pc3kgMyIsICJTdG9jaGFjdGljIE5vaXN5IDQiLCAiU3RvY2hhY3RpYyBOb2lzeSA1IiwgIlN0b2NoYWN0aWMgTm9pc3kgNiIpLCBjb2wgPSBjKCJibGFjayIsICJyZWQiLCAiZ3JlZW4iLCAieWVsbG93IiwgImJsdWUiLCAicHVycGxlIiwgIm9yYW5nZSIpLCBsdHkgPSAxLCBjZXggPSAwLjgpCmBgYAoKCmBgYHtyfQojIEluaXRpYWxpemUgbWF0cmljZXMgdG8gc3RvcmUgYXZlcmFnZXMgZm9yIGVhY2ggcG9zaXRpb24KYXZlcmFnZV9NTV9wb3MgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfU3RvY2hOb2lzeTFfcG9zIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX1N0b2NoTm9pc3kyX3BvcyA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKYXZlcmFnZV9TdG9jaE5vaXN5M19wb3MgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfU3RvY2hOb2lzeTRfcG9zIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX1N0b2NoTm9pc3k1X3BvcyA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKYXZlcmFnZV9TdG9jaE5vaXN5Nl9wb3MgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCgojIExvb3AgdGhyb3VnaCBlYWNoIHNpbXVsYXRpb24gKG4pCmZvciAobiBpbiAxOjEwKSB7CgogIE1NX3Bvc19zZXQxMiA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfMTJbbiwgN10pKSwgIiwgIikKCiAgU3RvY2hOb2lzeTFfcG9zX3NldDEyIDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c18xMltuLCA5XSkpLCAiLCAiKQogIAogIFN0b2NoTm9pc3kyX3Bvc19zZXQxMiA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfMTJbbiwgMTFdKSksICIsICIpCiAgCiAgU3RvY2hOb2lzeTNfcG9zX3NldDEyIDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c18xMltuLCAxM10pKSwgIiwgIikKICAKICBTdG9jaE5vaXN5NF9wb3Nfc2V0MTIgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzEyW24sIDE1XSkpLCAiLCAiKQogIAogIFN0b2NoTm9pc3k1X3Bvc19zZXQxMiA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfMTJbbiwgMTddKSksICIsICIpCiAgCiAgU3RvY2hOb2lzeTZfcG9zX3NldDEyIDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c18xMltuLCAxOV0pKSwgIiwgIikKICAKICAjIExvb3AgdGhyb3VnaCBlYWNoIHBvc2l0aW9uIChpKQogIGZvciAoaSBpbiAxOjEwMCkgewogICAgIyBFeHRyYWN0IFRydWUgYW5kIEV4cGVjdGVkIHZhbHVlcyBmb3IgdGhlIGktdGggcG9zaXRpb24KICAgIE1NX3BvcyA8LSBzYXBwbHkoTU1fcG9zX3NldDEyLCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgU3RvY2hOb2lzeTFfcG9zIDwtIHNhcHBseShTdG9jaE5vaXN5MV9wb3Nfc2V0MTIsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICBTdG9jaE5vaXN5Ml9wb3MgPC0gc2FwcGx5KFN0b2NoTm9pc3kyX3Bvc19zZXQxMiwgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIFN0b2NoTm9pc3kzX3BvcyA8LSBzYXBwbHkoU3RvY2hOb2lzeTNfcG9zX3NldDEyLCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgU3RvY2hOb2lzeTRfcG9zIDwtIHNhcHBseShTdG9jaE5vaXN5NF9wb3Nfc2V0MTIsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICBTdG9jaE5vaXN5NV9wb3MgPC0gc2FwcGx5KFN0b2NoTm9pc3k1X3Bvc19zZXQxMiwgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIFN0b2NoTm9pc3k2X3BvcyA8LSBzYXBwbHkoU3RvY2hOb2lzeTZfcG9zX3NldDEyLCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgCiAgICAjIENhbGN1bGF0ZSB0aGUgYXZlcmFnZSBvZiBUcnVlIGFuZCBFeHBlY3RlZCB2YWx1ZXMgZm9yIHRoZSBpLXRoIHBvc2l0aW9uCiAgICBhdmVyYWdlX01NX3Bvc1tpLCBuXSA8LSBtZWFuKE1NX3BvcywgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9TdG9jaE5vaXN5MV9wb3NbaSwgbl0gPC0gbWVhbihTdG9jaE5vaXN5MV9wb3MsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfU3RvY2hOb2lzeTJfcG9zW2ksIG5dIDwtIG1lYW4oU3RvY2hOb2lzeTJfcG9zLCBuYS5ybSA9IFRSVUUpCiAgICBhdmVyYWdlX1N0b2NoTm9pc3kzX3Bvc1tpLCBuXSA8LSBtZWFuKFN0b2NoTm9pc3kzX3BvcywgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9TdG9jaE5vaXN5NF9wb3NbaSwgbl0gPC0gbWVhbihTdG9jaE5vaXN5NF9wb3MsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfU3RvY2hOb2lzeTVfcG9zW2ksIG5dIDwtIG1lYW4oU3RvY2hOb2lzeTVfcG9zLCBuYS5ybSA9IFRSVUUpCiAgICBhdmVyYWdlX1N0b2NoTm9pc3k2X3Bvc1tpLCBuXSA8LSBtZWFuKFN0b2NoTm9pc3k2X3BvcywgbmEucm0gPSBUUlVFKQogIH0KfQoKIyBDYWxjdWxhdGUgdGhlIG92ZXJhbGwgYXZlcmFnZSBmb3IgZWFjaCBwb3NpdGlvbiBhY3Jvc3MgYWxsIHNpbXVsYXRpb25zCm92ZXJhbGxfYXZlcmFnZV9NTV9wb3MgPC0gcm93TWVhbnMoYXZlcmFnZV9NTV9wb3MsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX1N0b2NoTm9pc3kxX3BvcyA8LSByb3dNZWFucyhhdmVyYWdlX1N0b2NoTm9pc3kxX3BvcywgbmEucm0gPSBUUlVFKQpvdmVyYWxsX2F2ZXJhZ2VfU3RvY2hOb2lzeTJfcG9zIDwtIHJvd01lYW5zKGF2ZXJhZ2VfU3RvY2hOb2lzeTJfcG9zLCBuYS5ybSA9IFRSVUUpCm92ZXJhbGxfYXZlcmFnZV9TdG9jaE5vaXN5M19wb3MgPC0gcm93TWVhbnMoYXZlcmFnZV9TdG9jaE5vaXN5M19wb3MsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX1N0b2NoTm9pc3k0X3BvcyA8LSByb3dNZWFucyhhdmVyYWdlX1N0b2NoTm9pc3k0X3BvcywgbmEucm0gPSBUUlVFKQpvdmVyYWxsX2F2ZXJhZ2VfU3RvY2hOb2lzeTVfcG9zIDwtIHJvd01lYW5zKGF2ZXJhZ2VfU3RvY2hOb2lzeTVfcG9zLCBuYS5ybSA9IFRSVUUpCm92ZXJhbGxfYXZlcmFnZV9TdG9jaE5vaXN5Nl9wb3MgPC0gcm93TWVhbnMoYXZlcmFnZV9TdG9jaE5vaXN5Nl9wb3MsIG5hLnJtID0gVFJVRSkKCiMgUGxvdCB0aGUgb3ZlcmFsbCBhdmVyYWdlcwpwbG90KG92ZXJhbGxfYXZlcmFnZV9NTV9wb3MsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAiYmxhY2siLCBtYWluID0gIk92ZXJhbGwgQXZlcmFnZSBQb3NpdGlvbiIsIHhsYWIgPSAiUG9zaXRpb24gaW4gTGlzdCIsIHlsYWIgPSAiVmFsdWUiLCB5bGltID0gYyhtaW4oYyhvdmVyYWxsX2F2ZXJhZ2VfTU1fcG9zLCBvdmVyYWxsX2F2ZXJhZ2VfU3RvY2hOb2lzeTFfcG9zLCBvdmVyYWxsX2F2ZXJhZ2VfU3RvY2hOb2lzeTJfcG9zLCBvdmVyYWxsX2F2ZXJhZ2VfU3RvY2hOb2lzeTNfcG9zLCBvdmVyYWxsX2F2ZXJhZ2VfU3RvY2hOb2lzeTRfcG9zLCBvdmVyYWxsX2F2ZXJhZ2VfU3RvY2hOb2lzeTVfcG9zLCBvdmVyYWxsX2F2ZXJhZ2VfU3RvY2hOb2lzeTZfcG9zKSksIG1heChjKG92ZXJhbGxfYXZlcmFnZV9NTV9wb3MsIG92ZXJhbGxfYXZlcmFnZV9TdG9jaE5vaXN5MV9wb3MsIG92ZXJhbGxfYXZlcmFnZV9TdG9jaE5vaXN5Ml9wb3MsIG92ZXJhbGxfYXZlcmFnZV9TdG9jaE5vaXN5M19wb3MsIG92ZXJhbGxfYXZlcmFnZV9TdG9jaE5vaXN5NF9wb3MsIG92ZXJhbGxfYXZlcmFnZV9TdG9jaE5vaXN5NV9wb3MsIG92ZXJhbGxfYXZlcmFnZV9TdG9jaE5vaXN5Nl9wb3MpKSkpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9TdG9jaE5vaXN5MV9wb3MsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAicmVkIikKbGluZXMob3ZlcmFsbF9hdmVyYWdlX1N0b2NoTm9pc3kyX3BvcywgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJncmVlbiIpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9TdG9jaE5vaXN5M19wb3MsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAieWVsbG93IikKbGluZXMob3ZlcmFsbF9hdmVyYWdlX1N0b2NoTm9pc3k0X3BvcywgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJibHVlIikKbGluZXMob3ZlcmFsbF9hdmVyYWdlX1N0b2NoTm9pc3k1X3BvcywgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJwdXJwbGUiKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfU3RvY2hOb2lzeTZfcG9zLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gIm9yYW5nZSIpCgojIEFkZCBsZWdlbmQKbGVnZW5kKCJ0b3BsZWZ0IiwgbGVnZW5kID0gYygiTWFya2V0IE1ha2VyIiwgIlN0b2NoYXN0aWMgTm9pc3kgMSIsICJTdG9jaGFzdGljIE5vaXN5IDIiLCAiU3RvY2hhc3RpYyBOb2lzeSAzIiwgIlN0b2NoYXN0aWMgTm9pc3kgNCIsICJTdG9jaGFzdGljIE5vaXN5IDUiLCAiU3RvY2hhc3RpYyBOb2lzeSA2IiksIGNvbCA9IGMoImJsYWNrIiwgInJlZCIsICJncmVlbiIsICJ5ZWxsb3ciLCAiYmx1ZSIsICJwdXJwbGUiLCAib3JhbmdlIiksIGx0eSA9IDEsIGNleCA9IDAuOCkKYGBgCgoKCiMjIHNldDEzICg2IG5vaXN5IGluZm9ybWVkKQoKYGBge3J9CiMgSW5pdGlhbGl6ZSBtYXRyaWNlcyB0byBzdG9yZSBhdmVyYWdlcyBmb3IgZWFjaCBwb3NpdGlvbgphdmVyYWdlX2JpZCA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKYXZlcmFnZV9hc2sgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCgojIExvb3AgdGhyb3VnaCBlYWNoIHNpbXVsYXRpb24gKG4pCmZvciAobiBpbiAxOjEwKSB7CiAgIyBFeHRyYWN0IFRydWUgdmFsdWVzIGZyb20gdGhlIGFnZ3JlZ2F0ZWRfcmVzdWx0c180IGRhdGFmcmFtZQogIEJpZHNfc2V0MTMgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzEzW24sIDRdKSksICIsICIpCiAgCiAgIyBFeHRyYWN0IEV4cGVjdGVkIHZhbHVlcyBmcm9tIHRoZSBhZ2dyZWdhdGVkX3Jlc3VsdHNfNCBkYXRhZnJhbWUKICBBc2tzX3NldDEzIDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c18xM1tuLCA1XSkpLCAiLCAiKQogIAogICMgTG9vcCB0aHJvdWdoIGVhY2ggcG9zaXRpb24gKGkpCiAgZm9yIChpIGluIDE6MTAwKSB7CiAgICAjIEV4dHJhY3QgVHJ1ZSBhbmQgRXhwZWN0ZWQgdmFsdWVzIGZvciB0aGUgaS10aCBwb3NpdGlvbgogICAgQmlkcyA8LSBzYXBwbHkoQmlkc19zZXQxMywgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIEFza3MgPC0gc2FwcGx5KEFza3Nfc2V0MTMsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICAKICAgICMgQ2FsY3VsYXRlIHRoZSBhdmVyYWdlIG9mIFRydWUgYW5kIEV4cGVjdGVkIHZhbHVlcyBmb3IgdGhlIGktdGggcG9zaXRpb24KICAgIGF2ZXJhZ2VfYmlkW2ksIG5dIDwtIG1lYW4oQmlkcywgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9hc2tbaSwgbl0gPC0gbWVhbihBc2tzLCBuYS5ybSA9IFRSVUUpCiAgfQp9CgojIENhbGN1bGF0ZSB0aGUgb3ZlcmFsbCBhdmVyYWdlIGZvciBlYWNoIHBvc2l0aW9uIGFjcm9zcyBhbGwgc2ltdWxhdGlvbnMKb3ZlcmFsbF9hdmVyYWdlX2JpZCA8LSByb3dNZWFucyhhdmVyYWdlX2JpZCwgbmEucm0gPSBUUlVFKQpvdmVyYWxsX2F2ZXJhZ2VfYXNrIDwtIHJvd01lYW5zKGF2ZXJhZ2VfYXNrLCBuYS5ybSA9IFRSVUUpCgojIyBUcnVlIFZhbHVlCiMgSW5pdGlhbGl6ZSBtYXRyaWNlcyB0byBzdG9yZSBhdmVyYWdlcyBmb3IgZWFjaCBwb3NpdGlvbgphdmVyYWdlX3RydWUgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfZXhwZWN0ZWQgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCgojIExvb3AgdGhyb3VnaCBlYWNoIHNpbXVsYXRpb24gKG4pCmZvciAobiBpbiAxOjEwKSB7CiAgIyBFeHRyYWN0IFRydWUgdmFsdWVzIGZyb20gdGhlIGFnZ3JlZ2F0ZWRfcmVzdWx0c180IGRhdGFmcmFtZQogIFRydWVWYWx1ZXNfc2V0MTMgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzEzW24sIDJdKSksICIsICIpCiAgCiAgIyBFeHRyYWN0IEV4cGVjdGVkIHZhbHVlcyBmcm9tIHRoZSBhZ2dyZWdhdGVkX3Jlc3VsdHNfNCBkYXRhZnJhbWUKICBFeHBlY3RlZFZhbHVlc19zZXQxMyA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfMTNbbiwgM10pKSwgIiwgIikKICAKICAjIExvb3AgdGhyb3VnaCBlYWNoIHBvc2l0aW9uIChpKQogIGZvciAoaSBpbiAxOjEwMCkgewogICAgIyBFeHRyYWN0IFRydWUgYW5kIEV4cGVjdGVkIHZhbHVlcyBmb3IgdGhlIGktdGggcG9zaXRpb24KICAgIFRydWVfdmFsdWVzIDwtIHNhcHBseShUcnVlVmFsdWVzX3NldDEzLCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgRXhwZWN0ZWRfdmFsdWVzIDwtIHNhcHBseShFeHBlY3RlZFZhbHVlc19zZXQxMywgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIAogICAgIyBDYWxjdWxhdGUgdGhlIGF2ZXJhZ2Ugb2YgVHJ1ZSBhbmQgRXhwZWN0ZWQgdmFsdWVzIGZvciB0aGUgaS10aCBwb3NpdGlvbgogICAgYXZlcmFnZV90cnVlW2ksIG5dIDwtIG1lYW4oVHJ1ZV92YWx1ZXMsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfZXhwZWN0ZWRbaSwgbl0gPC0gbWVhbihFeHBlY3RlZF92YWx1ZXMsIG5hLnJtID0gVFJVRSkKICB9Cn0KCiMgQ2FsY3VsYXRlIHRoZSBvdmVyYWxsIGF2ZXJhZ2UgZm9yIGVhY2ggcG9zaXRpb24gYWNyb3NzIGFsbCBzaW11bGF0aW9ucwpvdmVyYWxsX2F2ZXJhZ2VfdHJ1ZSA8LSByb3dNZWFucyhhdmVyYWdlX3RydWUsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX2V4cGVjdGVkIDwtIHJvd01lYW5zKGF2ZXJhZ2VfZXhwZWN0ZWQsIG5hLnJtID0gVFJVRSkKCiMgUGxvdCB0aGUgb3ZlcmFsbCBhdmVyYWdlcwojcGxvdChvdmVyYWxsX2F2ZXJhZ2VfdHJ1ZSwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJibHVlIiwgbWFpbiA9ICJPdmVyYWxsIEF2ZXJhZ2Ugb2YgVHJ1ZSB2cyBFeHBlY3RlZCBWYWx1ZXMiLCB4bGFiID0gIlBvc2l0aW9uIGluIExpc3QiLCB5bGFiID0gIlZhbHVlIiwgeWxpbSA9IGMobWluKGMob3ZlcmFsbF9hdmVyYWdlX3RydWUsIG92ZXJhbGxfYXZlcmFnZV9leHBlY3RlZCkpLCBtYXgoYyhvdmVyYWxsX2F2ZXJhZ2VfdHJ1ZSwgb3ZlcmFsbF9hdmVyYWdlX2V4cGVjdGVkKSkpKQojbGluZXMob3ZlcmFsbF9hdmVyYWdlX2V4cGVjdGVkLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gInJlZCIpCiNsZWdlbmQoInRvcHJpZ2h0IiwgbGVnZW5kID0gYygiVHJ1ZSBWYWx1ZXMiLCAiRXhwZWN0ZWQgVmFsdWVzIiksIGNvbCA9IGMoImJsdWUiLCAicmVkIiksIGx0eSA9IDEsIGNleCA9IDAuOCkKCiMgUGxvdCB0aGUgb3ZlcmFsbCBhdmVyYWdlcwpwbG90KG92ZXJhbGxfYXZlcmFnZV9iaWQsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAiYmx1ZSIsIG1haW4gPSAiT3ZlcmFsbCBBdmVyYWdlIG9mIEJpZHMgdnMgQXNrcyAmIFRydWUgdnMgRXhwZWN0ZWQgVmFsdWVzIiwgeGxhYiA9ICJQb3NpdGlvbiBpbiBMaXN0IiwgeWxhYiA9ICJWYWx1ZSIsIHlsaW0gPSBjKG1pbihjKG92ZXJhbGxfYXZlcmFnZV9iaWQsIG92ZXJhbGxfYXZlcmFnZV9hc2ssIG92ZXJhbGxfYXZlcmFnZV90cnVlLCBvdmVyYWxsX2F2ZXJhZ2VfZXhwZWN0ZWQpKSwgbWF4KGMob3ZlcmFsbF9hdmVyYWdlX2JpZCwgb3ZlcmFsbF9hdmVyYWdlX2Fzaywgb3ZlcmFsbF9hdmVyYWdlX3RydWUsIG92ZXJhbGxfYXZlcmFnZV9leHBlY3RlZCkpKSkKbGluZXMob3ZlcmFsbF9hdmVyYWdlX2FzaywgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJyZWQiKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfdHJ1ZSwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJncmVlbiIpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9leHBlY3RlZCwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJwdXJwbGUiKQpsZWdlbmQoImJvdHRvbWxlZnQiLCBsZWdlbmQgPSBjKCJCaWRzIiwgIkFza3MiLCAiVHJ1ZSBWYWx1ZSIsICJFeHBlY3RlZCBWYWx1ZSIpLCBjb2wgPSBjKCJibHVlIiwgInJlZCIsICJncmVlbiIsICJwdXJwbGUiKSwgbHR5ID0gMSwgY2V4ID0gMC44KQpgYGAKCmBgYHtyfQojIEluaXRpYWxpemUgbWF0cmljZXMgdG8gc3RvcmUgYXZlcmFnZXMgZm9yIGVhY2ggcG9zaXRpb24KYXZlcmFnZV9NTV9wbmwgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfTm9pc3lJbmZvcm1lZDFfcG5sIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX05vaXN5SW5mb3JtZWQyX3BubCA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKYXZlcmFnZV9Ob2lzeUluZm9ybWVkM19wbmwgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfTm9pc3lJbmZvcm1lZDRfcG5sIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX05vaXN5SW5mb3JtZWQ1X3BubCA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKYXZlcmFnZV9Ob2lzeUluZm9ybWVkNl9wbmwgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCgojIExvb3AgdGhyb3VnaCBlYWNoIHNpbXVsYXRpb24gKG4pCmZvciAobiBpbiAxOjEwKSB7CgogIE1NX3BubF9zZXQxMyA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfMTNbbiwgNl0pKSwgIiwgIikKCiAgTm9pc3lJbmZvcm1lZDFfcG5sX3NldDEzIDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c18xM1tuLCA4XSkpLCAiLCAiKQogIAogIE5vaXN5SW5mb3JtZWQyX3BubF9zZXQxMyA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfMTNbbiwgMTBdKSksICIsICIpCiAgCiAgTm9pc3lJbmZvcm1lZDNfcG5sX3NldDEzIDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c18xM1tuLCAxMl0pKSwgIiwgIikKICAKICBOb2lzeUluZm9ybWVkNF9wbmxfc2V0MTMgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzEzW24sIDE0XSkpLCAiLCAiKQogIAogIE5vaXN5SW5mb3JtZWQ1X3BubF9zZXQxMyA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfMTNbbiwgMTZdKSksICIsICIpCiAgCiAgTm9pc3lJbmZvcm1lZDZfcG5sX3NldDEzIDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c18xM1tuLCAxOF0pKSwgIiwgIikKICAKICAjIExvb3AgdGhyb3VnaCBlYWNoIHBvc2l0aW9uIChpKQogIGZvciAoaSBpbiAxOjEwMCkgewogICAgIyBFeHRyYWN0IFRydWUgYW5kIEV4cGVjdGVkIHZhbHVlcyBmb3IgdGhlIGktdGggcG9zaXRpb24KICAgIE1NX3BubCA8LSBzYXBwbHkoTU1fcG5sX3NldDEzLCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgTm9pc3lJbmZvcm1lZDFfcG5sIDwtIHNhcHBseShOb2lzeUluZm9ybWVkMV9wbmxfc2V0MTMsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICBOb2lzeUluZm9ybWVkMl9wbmwgPC0gc2FwcGx5KE5vaXN5SW5mb3JtZWQyX3BubF9zZXQxMywgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIE5vaXN5SW5mb3JtZWQzX3BubCA8LSBzYXBwbHkoTm9pc3lJbmZvcm1lZDNfcG5sX3NldDEzLCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgTm9pc3lJbmZvcm1lZDRfcG5sIDwtIHNhcHBseShOb2lzeUluZm9ybWVkNF9wbmxfc2V0MTMsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICBOb2lzeUluZm9ybWVkNV9wbmwgPC0gc2FwcGx5KE5vaXN5SW5mb3JtZWQ1X3BubF9zZXQxMywgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIE5vaXN5SW5mb3JtZWQ2X3BubCA8LSBzYXBwbHkoTm9pc3lJbmZvcm1lZDZfcG5sX3NldDEzLCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgCiAgICAjIENhbGN1bGF0ZSB0aGUgYXZlcmFnZSBvZiBUcnVlIGFuZCBFeHBlY3RlZCB2YWx1ZXMgZm9yIHRoZSBpLXRoIHBvc2l0aW9uCiAgICBhdmVyYWdlX01NX3BubFtpLCBuXSA8LSBtZWFuKE1NX3BubCwgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9Ob2lzeUluZm9ybWVkMV9wbmxbaSwgbl0gPC0gbWVhbihOb2lzeUluZm9ybWVkMV9wbmwsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfTm9pc3lJbmZvcm1lZDJfcG5sW2ksIG5dIDwtIG1lYW4oTm9pc3lJbmZvcm1lZDJfcG5sLCBuYS5ybSA9IFRSVUUpCiAgICBhdmVyYWdlX05vaXN5SW5mb3JtZWQzX3BubFtpLCBuXSA8LSBtZWFuKE5vaXN5SW5mb3JtZWQzX3BubCwgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9Ob2lzeUluZm9ybWVkNF9wbmxbaSwgbl0gPC0gbWVhbihOb2lzeUluZm9ybWVkNF9wbmwsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfTm9pc3lJbmZvcm1lZDVfcG5sW2ksIG5dIDwtIG1lYW4oTm9pc3lJbmZvcm1lZDVfcG5sLCBuYS5ybSA9IFRSVUUpCiAgICBhdmVyYWdlX05vaXN5SW5mb3JtZWQ2X3BubFtpLCBuXSA8LSBtZWFuKE5vaXN5SW5mb3JtZWQ2X3BubCwgbmEucm0gPSBUUlVFKQogIH0KfQoKIyBDYWxjdWxhdGUgdGhlIG92ZXJhbGwgYXZlcmFnZSBmb3IgZWFjaCBwb3NpdGlvbiBhY3Jvc3MgYWxsIHNpbXVsYXRpb25zCm92ZXJhbGxfYXZlcmFnZV9NTV9wbmwgPC0gcm93TWVhbnMoYXZlcmFnZV9NTV9wbmwsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX05vaXN5SW5mb3JtZWQxX3BubCA8LSByb3dNZWFucyhhdmVyYWdlX05vaXN5SW5mb3JtZWQxX3BubCwgbmEucm0gPSBUUlVFKQpvdmVyYWxsX2F2ZXJhZ2VfTm9pc3lJbmZvcm1lZDJfcG5sIDwtIHJvd01lYW5zKGF2ZXJhZ2VfTm9pc3lJbmZvcm1lZDJfcG5sLCBuYS5ybSA9IFRSVUUpCm92ZXJhbGxfYXZlcmFnZV9Ob2lzeUluZm9ybWVkM19wbmwgPC0gcm93TWVhbnMoYXZlcmFnZV9Ob2lzeUluZm9ybWVkM19wbmwsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX05vaXN5SW5mb3JtZWQ0X3BubCA8LSByb3dNZWFucyhhdmVyYWdlX05vaXN5SW5mb3JtZWQ0X3BubCwgbmEucm0gPSBUUlVFKQpvdmVyYWxsX2F2ZXJhZ2VfTm9pc3lJbmZvcm1lZDVfcG5sIDwtIHJvd01lYW5zKGF2ZXJhZ2VfTm9pc3lJbmZvcm1lZDVfcG5sLCBuYS5ybSA9IFRSVUUpCm92ZXJhbGxfYXZlcmFnZV9Ob2lzeUluZm9ybWVkNl9wbmwgPC0gcm93TWVhbnMoYXZlcmFnZV9Ob2lzeUluZm9ybWVkNl9wbmwsIG5hLnJtID0gVFJVRSkKCiMgUGxvdCB0aGUgb3ZlcmFsbCBhdmVyYWdlcwpwbG90KG92ZXJhbGxfYXZlcmFnZV9NTV9wbmwsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAiYmxhY2siLCBtYWluID0gIk92ZXJhbGwgQXZlcmFnZSBQTkwiLCB4bGFiID0gIlBvc2l0aW9uIGluIExpc3QiLCB5bGFiID0gIlZhbHVlIiwgeWxpbSA9IGMobWluKGMob3ZlcmFsbF9hdmVyYWdlX01NX3BubCwgb3ZlcmFsbF9hdmVyYWdlX05vaXN5SW5mb3JtZWQxX3BubCwgb3ZlcmFsbF9hdmVyYWdlX05vaXN5SW5mb3JtZWQyX3BubCwgb3ZlcmFsbF9hdmVyYWdlX05vaXN5SW5mb3JtZWQzX3BubCwgb3ZlcmFsbF9hdmVyYWdlX05vaXN5SW5mb3JtZWQ0X3BubCwgb3ZlcmFsbF9hdmVyYWdlX05vaXN5SW5mb3JtZWQ1X3BubCwgb3ZlcmFsbF9hdmVyYWdlX05vaXN5SW5mb3JtZWQ2X3BubCkpLCBtYXgoYyhvdmVyYWxsX2F2ZXJhZ2VfTU1fcG5sLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3lJbmZvcm1lZDFfcG5sLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3lJbmZvcm1lZDJfcG5sLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3lJbmZvcm1lZDNfcG5sLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3lJbmZvcm1lZDRfcG5sLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3lJbmZvcm1lZDVfcG5sLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3lJbmZvcm1lZDZfcG5sKSkpKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfTm9pc3lJbmZvcm1lZDFfcG5sLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gInJlZCIpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9Ob2lzeUluZm9ybWVkMl9wbmwsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAiZ3JlZW4iKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfTm9pc3lJbmZvcm1lZDNfcG5sLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gInllbGxvdyIpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9Ob2lzeUluZm9ybWVkNF9wbmwsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAiYmx1ZSIpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9Ob2lzeUluZm9ybWVkNV9wbmwsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAicHVycGxlIikKbGluZXMob3ZlcmFsbF9hdmVyYWdlX05vaXN5SW5mb3JtZWQ2X3BubCwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJvcmFuZ2UiKQoKIyBBZGQgbGVnZW5kCmxlZ2VuZCgiYm90dG9tbGVmdCIsIGxlZ2VuZCA9IGMoIk1hcmtldCBNYWtlciIsICJOb2lzeSBJbmZvcm1lZCAxIiwgIk5vaXN5IEluZm9ybWVkIDIiLCAiTm9pc3kgSW5mb3JtZWQgMyIsICJOb2lzeSBJbmZvcm1lZCA0IiwgIk5vaXN5IEluZm9ybWVkIDUiLCAiTm9pc3kgSW5mb3JtZWQgNiIpLCBjb2wgPSBjKCJibGFjayIsICJyZWQiLCAiZ3JlZW4iLCAieWVsbG93IiwgImJsdWUiLCAicHVycGxlIiwgIm9yYW5nZSIpLCBsdHkgPSAxLCBjZXggPSAwLjgpCmBgYAoKCmBgYHtyfQojIEluaXRpYWxpemUgbWF0cmljZXMgdG8gc3RvcmUgYXZlcmFnZXMgZm9yIGVhY2ggcG9zaXRpb24KYXZlcmFnZV9NTV9wb3MgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfTm9pc3lJbmZvcm1lZDFfcG9zIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX05vaXN5SW5mb3JtZWQyX3BvcyA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKYXZlcmFnZV9Ob2lzeUluZm9ybWVkM19wb3MgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfTm9pc3lJbmZvcm1lZDRfcG9zIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX05vaXN5SW5mb3JtZWQ1X3BvcyA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKYXZlcmFnZV9Ob2lzeUluZm9ybWVkNl9wb3MgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCgojIExvb3AgdGhyb3VnaCBlYWNoIHNpbXVsYXRpb24gKG4pCmZvciAobiBpbiAxOjEwKSB7CgogIE1NX3Bvc19zZXQxMyA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfMTNbbiwgN10pKSwgIiwgIikKCiAgTm9pc3lJbmZvcm1lZDFfcG9zX3NldDEzIDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c18xM1tuLCA5XSkpLCAiLCAiKQogIAogIE5vaXN5SW5mb3JtZWQyX3Bvc19zZXQxMyA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfMTNbbiwgMTFdKSksICIsICIpCiAgCiAgTm9pc3lJbmZvcm1lZDNfcG9zX3NldDEzIDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c18xM1tuLCAxM10pKSwgIiwgIikKICAKICBOb2lzeUluZm9ybWVkNF9wb3Nfc2V0MTMgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzEzW24sIDE1XSkpLCAiLCAiKQogIAogIE5vaXN5SW5mb3JtZWQ1X3Bvc19zZXQxMyA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfMTNbbiwgMTddKSksICIsICIpCiAgCiAgTm9pc3lJbmZvcm1lZDZfcG9zX3NldDEzIDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c18xM1tuLCAxOV0pKSwgIiwgIikKICAKICAjIExvb3AgdGhyb3VnaCBlYWNoIHBvc2l0aW9uIChpKQogIGZvciAoaSBpbiAxOjEwMCkgewogICAgIyBFeHRyYWN0IFRydWUgYW5kIEV4cGVjdGVkIHZhbHVlcyBmb3IgdGhlIGktdGggcG9zaXRpb24KICAgIE1NX3BvcyA8LSBzYXBwbHkoTU1fcG9zX3NldDEzLCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgTm9pc3lJbmZvcm1lZDFfcG9zIDwtIHNhcHBseShOb2lzeUluZm9ybWVkMV9wb3Nfc2V0MTMsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICBOb2lzeUluZm9ybWVkMl9wb3MgPC0gc2FwcGx5KE5vaXN5SW5mb3JtZWQyX3Bvc19zZXQxMywgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIE5vaXN5SW5mb3JtZWQzX3BvcyA8LSBzYXBwbHkoTm9pc3lJbmZvcm1lZDNfcG9zX3NldDEzLCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgTm9pc3lJbmZvcm1lZDRfcG9zIDwtIHNhcHBseShOb2lzeUluZm9ybWVkNF9wb3Nfc2V0MTMsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICBOb2lzeUluZm9ybWVkNV9wb3MgPC0gc2FwcGx5KE5vaXN5SW5mb3JtZWQ1X3Bvc19zZXQxMywgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIE5vaXN5SW5mb3JtZWQ2X3BvcyA8LSBzYXBwbHkoTm9pc3lJbmZvcm1lZDZfcG9zX3NldDEzLCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgCiAgICAjIENhbGN1bGF0ZSB0aGUgYXZlcmFnZSBvZiBUcnVlIGFuZCBFeHBlY3RlZCB2YWx1ZXMgZm9yIHRoZSBpLXRoIHBvc2l0aW9uCiAgICBhdmVyYWdlX01NX3Bvc1tpLCBuXSA8LSBtZWFuKE1NX3BvcywgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9Ob2lzeUluZm9ybWVkMV9wb3NbaSwgbl0gPC0gbWVhbihOb2lzeUluZm9ybWVkMV9wb3MsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfTm9pc3lJbmZvcm1lZDJfcG9zW2ksIG5dIDwtIG1lYW4oTm9pc3lJbmZvcm1lZDJfcG9zLCBuYS5ybSA9IFRSVUUpCiAgICBhdmVyYWdlX05vaXN5SW5mb3JtZWQzX3Bvc1tpLCBuXSA8LSBtZWFuKE5vaXN5SW5mb3JtZWQzX3BvcywgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9Ob2lzeUluZm9ybWVkNF9wb3NbaSwgbl0gPC0gbWVhbihOb2lzeUluZm9ybWVkNF9wb3MsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfTm9pc3lJbmZvcm1lZDVfcG9zW2ksIG5dIDwtIG1lYW4oTm9pc3lJbmZvcm1lZDVfcG9zLCBuYS5ybSA9IFRSVUUpCiAgICBhdmVyYWdlX05vaXN5SW5mb3JtZWQ2X3Bvc1tpLCBuXSA8LSBtZWFuKE5vaXN5SW5mb3JtZWQ2X3BvcywgbmEucm0gPSBUUlVFKQogIH0KfQoKIyBDYWxjdWxhdGUgdGhlIG92ZXJhbGwgYXZlcmFnZSBmb3IgZWFjaCBwb3NpdGlvbiBhY3Jvc3MgYWxsIHNpbXVsYXRpb25zCm92ZXJhbGxfYXZlcmFnZV9NTV9wb3MgPC0gcm93TWVhbnMoYXZlcmFnZV9NTV9wb3MsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX05vaXN5SW5mb3JtZWQxX3BvcyA8LSByb3dNZWFucyhhdmVyYWdlX05vaXN5SW5mb3JtZWQxX3BvcywgbmEucm0gPSBUUlVFKQpvdmVyYWxsX2F2ZXJhZ2VfTm9pc3lJbmZvcm1lZDJfcG9zIDwtIHJvd01lYW5zKGF2ZXJhZ2VfTm9pc3lJbmZvcm1lZDJfcG9zLCBuYS5ybSA9IFRSVUUpCm92ZXJhbGxfYXZlcmFnZV9Ob2lzeUluZm9ybWVkM19wb3MgPC0gcm93TWVhbnMoYXZlcmFnZV9Ob2lzeUluZm9ybWVkM19wb3MsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX05vaXN5SW5mb3JtZWQ0X3BvcyA8LSByb3dNZWFucyhhdmVyYWdlX05vaXN5SW5mb3JtZWQ0X3BvcywgbmEucm0gPSBUUlVFKQpvdmVyYWxsX2F2ZXJhZ2VfTm9pc3lJbmZvcm1lZDVfcG9zIDwtIHJvd01lYW5zKGF2ZXJhZ2VfTm9pc3lJbmZvcm1lZDVfcG9zLCBuYS5ybSA9IFRSVUUpCm92ZXJhbGxfYXZlcmFnZV9Ob2lzeUluZm9ybWVkNl9wb3MgPC0gcm93TWVhbnMoYXZlcmFnZV9Ob2lzeUluZm9ybWVkNl9wb3MsIG5hLnJtID0gVFJVRSkKCiMgUGxvdCB0aGUgb3ZlcmFsbCBhdmVyYWdlcwpwbG90KG92ZXJhbGxfYXZlcmFnZV9NTV9wb3MsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAiYmxhY2siLCBtYWluID0gIk92ZXJhbGwgQXZlcmFnZSBQb3NpdGlvbiIsIHhsYWIgPSAiUG9zaXRpb24gaW4gTGlzdCIsIHlsYWIgPSAiVmFsdWUiLCB5bGltID0gYyhtaW4oYyhvdmVyYWxsX2F2ZXJhZ2VfTU1fcG9zLCBvdmVyYWxsX2F2ZXJhZ2VfU3RvY2hOb2lzeTFfcG9zLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3lJbmZvcm1lZDJfcG9zLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3lJbmZvcm1lZDNfcG9zLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3lJbmZvcm1lZDRfcG9zLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3lJbmZvcm1lZDVfcG9zLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3lJbmZvcm1lZDZfcG9zKSksIG1heChjKG92ZXJhbGxfYXZlcmFnZV9NTV9wb3MsIG92ZXJhbGxfYXZlcmFnZV9Ob2lzeUluZm9ybWVkMV9wb3MsIG92ZXJhbGxfYXZlcmFnZV9Ob2lzeUluZm9ybWVkMl9wb3MsIG92ZXJhbGxfYXZlcmFnZV9Ob2lzeUluZm9ybWVkM19wb3MsIG92ZXJhbGxfYXZlcmFnZV9Ob2lzeUluZm9ybWVkNF9wb3MsIG92ZXJhbGxfYXZlcmFnZV9Ob2lzeUluZm9ybWVkNV9wb3MsIG92ZXJhbGxfYXZlcmFnZV9Ob2lzeUluZm9ybWVkNl9wb3MpKSkpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9Ob2lzeUluZm9ybWVkMV9wb3MsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAicmVkIikKbGluZXMob3ZlcmFsbF9hdmVyYWdlX05vaXN5SW5mb3JtZWQyX3BvcywgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJncmVlbiIpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9Ob2lzeUluZm9ybWVkM19wb3MsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAieWVsbG93IikKbGluZXMob3ZlcmFsbF9hdmVyYWdlX05vaXN5SW5mb3JtZWQ0X3BvcywgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJibHVlIikKbGluZXMob3ZlcmFsbF9hdmVyYWdlX05vaXN5SW5mb3JtZWQ1X3BvcywgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJwdXJwbGUiKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfTm9pc3lJbmZvcm1lZDZfcG9zLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gIm9yYW5nZSIpCgojIEFkZCBsZWdlbmQKbGVnZW5kKCJ0b3BsZWZ0IiwgbGVnZW5kID0gYygiTWFya2V0IE1ha2VyIiwgIk5vaXN5IEluZm9ybWVkIDEiLCAiTm9pc3kgSW5mb3JtZWQgMiIsICJOb2lzeSBJbmZvcm1lZCAzIiwgIk5vaXN5IEluZm9ybWVkIDQiLCAiTm9pc3kgSW5mb3JtZWQgNSIsICJOb2lzeSBJbmZvcm1lZCA2IiksIGNvbCA9IGMoImJsYWNrIiwgInJlZCIsICJncmVlbiIsICJ5ZWxsb3ciLCAiYmx1ZSIsICJwdXJwbGUiLCAib3JhbmdlIiksIGx0eSA9IDEsIGNleCA9IDAuOCkKYGBgCgoKCiMjIHNldDE0ICgxIGluZm9ybWVkICsgMiBub2lzeSBpbmZvcm1lZCArIDIgbm9pc3kgKyAxIG1lYW4gcmV2ZXJzaW9uKQoKYGBge3J9CiMgSW5pdGlhbGl6ZSBtYXRyaWNlcyB0byBzdG9yZSBhdmVyYWdlcyBmb3IgZWFjaCBwb3NpdGlvbgphdmVyYWdlX2JpZCA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKYXZlcmFnZV9hc2sgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCgojIExvb3AgdGhyb3VnaCBlYWNoIHNpbXVsYXRpb24gKG4pCmZvciAobiBpbiAxOjEwKSB7CiAgIyBFeHRyYWN0IFRydWUgdmFsdWVzIGZyb20gdGhlIGFnZ3JlZ2F0ZWRfcmVzdWx0c180IGRhdGFmcmFtZQogIEJpZHNfc2V0MTQgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzE0W24sIDRdKSksICIsICIpCiAgCiAgIyBFeHRyYWN0IEV4cGVjdGVkIHZhbHVlcyBmcm9tIHRoZSBhZ2dyZWdhdGVkX3Jlc3VsdHNfNCBkYXRhZnJhbWUKICBBc2tzX3NldDE0IDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c18xNFtuLCA1XSkpLCAiLCAiKQogIAogICMgTG9vcCB0aHJvdWdoIGVhY2ggcG9zaXRpb24gKGkpCiAgZm9yIChpIGluIDE6MTAwKSB7CiAgICAjIEV4dHJhY3QgVHJ1ZSBhbmQgRXhwZWN0ZWQgdmFsdWVzIGZvciB0aGUgaS10aCBwb3NpdGlvbgogICAgQmlkcyA8LSBzYXBwbHkoQmlkc19zZXQxNCwgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIEFza3MgPC0gc2FwcGx5KEFza3Nfc2V0MTQsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICAKICAgICMgQ2FsY3VsYXRlIHRoZSBhdmVyYWdlIG9mIFRydWUgYW5kIEV4cGVjdGVkIHZhbHVlcyBmb3IgdGhlIGktdGggcG9zaXRpb24KICAgIGF2ZXJhZ2VfYmlkW2ksIG5dIDwtIG1lYW4oQmlkcywgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9hc2tbaSwgbl0gPC0gbWVhbihBc2tzLCBuYS5ybSA9IFRSVUUpCiAgfQp9CgojIENhbGN1bGF0ZSB0aGUgb3ZlcmFsbCBhdmVyYWdlIGZvciBlYWNoIHBvc2l0aW9uIGFjcm9zcyBhbGwgc2ltdWxhdGlvbnMKb3ZlcmFsbF9hdmVyYWdlX2JpZCA8LSByb3dNZWFucyhhdmVyYWdlX2JpZCwgbmEucm0gPSBUUlVFKQpvdmVyYWxsX2F2ZXJhZ2VfYXNrIDwtIHJvd01lYW5zKGF2ZXJhZ2VfYXNrLCBuYS5ybSA9IFRSVUUpCgojIyBUcnVlIFZhbHVlCiMgSW5pdGlhbGl6ZSBtYXRyaWNlcyB0byBzdG9yZSBhdmVyYWdlcyBmb3IgZWFjaCBwb3NpdGlvbgphdmVyYWdlX3RydWUgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfZXhwZWN0ZWQgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCgojIExvb3AgdGhyb3VnaCBlYWNoIHNpbXVsYXRpb24gKG4pCmZvciAobiBpbiAxOjEwKSB7CiAgIyBFeHRyYWN0IFRydWUgdmFsdWVzIGZyb20gdGhlIGFnZ3JlZ2F0ZWRfcmVzdWx0c180IGRhdGFmcmFtZQogIFRydWVWYWx1ZXNfc2V0MTQgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzE0W24sIDJdKSksICIsICIpCiAgCiAgIyBFeHRyYWN0IEV4cGVjdGVkIHZhbHVlcyBmcm9tIHRoZSBhZ2dyZWdhdGVkX3Jlc3VsdHNfNCBkYXRhZnJhbWUKICBFeHBlY3RlZFZhbHVlc19zZXQxNCA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfMTRbbiwgM10pKSwgIiwgIikKICAKICAjIExvb3AgdGhyb3VnaCBlYWNoIHBvc2l0aW9uIChpKQogIGZvciAoaSBpbiAxOjEwMCkgewogICAgIyBFeHRyYWN0IFRydWUgYW5kIEV4cGVjdGVkIHZhbHVlcyBmb3IgdGhlIGktdGggcG9zaXRpb24KICAgIFRydWVfdmFsdWVzIDwtIHNhcHBseShUcnVlVmFsdWVzX3NldDE0LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgRXhwZWN0ZWRfdmFsdWVzIDwtIHNhcHBseShFeHBlY3RlZFZhbHVlc19zZXQxNCwgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIAogICAgIyBDYWxjdWxhdGUgdGhlIGF2ZXJhZ2Ugb2YgVHJ1ZSBhbmQgRXhwZWN0ZWQgdmFsdWVzIGZvciB0aGUgaS10aCBwb3NpdGlvbgogICAgYXZlcmFnZV90cnVlW2ksIG5dIDwtIG1lYW4oVHJ1ZV92YWx1ZXMsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfZXhwZWN0ZWRbaSwgbl0gPC0gbWVhbihFeHBlY3RlZF92YWx1ZXMsIG5hLnJtID0gVFJVRSkKICB9Cn0KCiMgQ2FsY3VsYXRlIHRoZSBvdmVyYWxsIGF2ZXJhZ2UgZm9yIGVhY2ggcG9zaXRpb24gYWNyb3NzIGFsbCBzaW11bGF0aW9ucwpvdmVyYWxsX2F2ZXJhZ2VfdHJ1ZSA8LSByb3dNZWFucyhhdmVyYWdlX3RydWUsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX2V4cGVjdGVkIDwtIHJvd01lYW5zKGF2ZXJhZ2VfZXhwZWN0ZWQsIG5hLnJtID0gVFJVRSkKCiMgUGxvdCB0aGUgb3ZlcmFsbCBhdmVyYWdlcwojcGxvdChvdmVyYWxsX2F2ZXJhZ2VfdHJ1ZSwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJibHVlIiwgbWFpbiA9ICJPdmVyYWxsIEF2ZXJhZ2Ugb2YgVHJ1ZSB2cyBFeHBlY3RlZCBWYWx1ZXMiLCB4bGFiID0gIlBvc2l0aW9uIGluIExpc3QiLCB5bGFiID0gIlZhbHVlIiwgeWxpbSA9IGMobWluKGMob3ZlcmFsbF9hdmVyYWdlX3RydWUsIG92ZXJhbGxfYXZlcmFnZV9leHBlY3RlZCkpLCBtYXgoYyhvdmVyYWxsX2F2ZXJhZ2VfdHJ1ZSwgb3ZlcmFsbF9hdmVyYWdlX2V4cGVjdGVkKSkpKQojbGluZXMob3ZlcmFsbF9hdmVyYWdlX2V4cGVjdGVkLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gInJlZCIpCiNsZWdlbmQoInRvcHJpZ2h0IiwgbGVnZW5kID0gYygiVHJ1ZSBWYWx1ZXMiLCAiRXhwZWN0ZWQgVmFsdWVzIiksIGNvbCA9IGMoImJsdWUiLCAicmVkIiksIGx0eSA9IDEsIGNleCA9IDAuOCkKCiMgUGxvdCB0aGUgb3ZlcmFsbCBhdmVyYWdlcwpwbG90KG92ZXJhbGxfYXZlcmFnZV9iaWQsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAiYmx1ZSIsIG1haW4gPSAiT3ZlcmFsbCBBdmVyYWdlIG9mIEJpZHMgdnMgQXNrcyAmIFRydWUgdnMgRXhwZWN0ZWQgVmFsdWVzIiwgeGxhYiA9ICJQb3NpdGlvbiBpbiBMaXN0IiwgeWxhYiA9ICJWYWx1ZSIsIHlsaW0gPSBjKG1pbihjKG92ZXJhbGxfYXZlcmFnZV9iaWQsIG92ZXJhbGxfYXZlcmFnZV9hc2ssIG92ZXJhbGxfYXZlcmFnZV90cnVlLCBvdmVyYWxsX2F2ZXJhZ2VfZXhwZWN0ZWQpKSwgbWF4KGMob3ZlcmFsbF9hdmVyYWdlX2JpZCwgb3ZlcmFsbF9hdmVyYWdlX2Fzaywgb3ZlcmFsbF9hdmVyYWdlX3RydWUsIG92ZXJhbGxfYXZlcmFnZV9leHBlY3RlZCkpKSkKbGluZXMob3ZlcmFsbF9hdmVyYWdlX2FzaywgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJyZWQiKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfdHJ1ZSwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJncmVlbiIpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9leHBlY3RlZCwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJwdXJwbGUiKQpsZWdlbmQoImJvdHRvbWxlZnQiLCBsZWdlbmQgPSBjKCJCaWRzIiwgIkFza3MiLCAiVHJ1ZSBWYWx1ZSIsICJFeHBlY3RlZCBWYWx1ZSIpLCBjb2wgPSBjKCJibHVlIiwgInJlZCIsICJncmVlbiIsICJwdXJwbGUiKSwgbHR5ID0gMSwgY2V4ID0gMC44KQpgYGAKCmBgYHtyfQojIEluaXRpYWxpemUgbWF0cmljZXMgdG8gc3RvcmUgYXZlcmFnZXMgZm9yIGVhY2ggcG9zaXRpb24KYXZlcmFnZV9NTV9wbmwgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfSW5mb3JtZWRfcG5sIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX05vaXN5SW5mb3JtZWQxX3BubCA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKYXZlcmFnZV9Ob2lzeUluZm9ybWVkMl9wbmwgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfTm9pc3kxX3BubCA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKYXZlcmFnZV9Ob2lzeTJfcG5sIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX21yX3BubCA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKCiMgTG9vcCB0aHJvdWdoIGVhY2ggc2ltdWxhdGlvbiAobikKZm9yIChuIGluIDE6MTApIHsKCiAgTU1fcG5sX3NldDE0IDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c18xNFtuLCA2XSkpLCAiLCAiKQoKICBJbmZvcm1lZF9wbmxfc2V0MTQgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzE0W24sIDhdKSksICIsICIpCiAgCiAgTm9pc3lJbmZvcm1lZDFfcG5sX3NldDE0IDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c18xNFtuLCAxMF0pKSwgIiwgIikKICAKICBOb2lzeUluZm9ybWVkMl9wbmxfc2V0MTQgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzE0W24sIDEyXSkpLCAiLCAiKQogIAogIE5vaXN5MV9wbmxfc2V0MTQgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzE0W24sIDE0XSkpLCAiLCAiKQogIAogIE5vaXN5Ml9wbmxfc2V0MTQgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzE0W24sIDE2XSkpLCAiLCAiKQogIAogIG1yX3BubF9zZXQxNCA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfMTRbbiwgMThdKSksICIsICIpCiAgCiAgIyBMb29wIHRocm91Z2ggZWFjaCBwb3NpdGlvbiAoaSkKICBmb3IgKGkgaW4gMToxMDApIHsKICAgICMgRXh0cmFjdCBUcnVlIGFuZCBFeHBlY3RlZCB2YWx1ZXMgZm9yIHRoZSBpLXRoIHBvc2l0aW9uCiAgICBNTV9wbmwgPC0gc2FwcGx5KE1NX3BubF9zZXQxNCwgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIEluZm9ybWVkX3BubCA8LSBzYXBwbHkoSW5mb3JtZWRfcG5sX3NldDE0LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgTm9pc3lJbmZvcm1lZDFfcG5sIDwtIHNhcHBseShOb2lzeUluZm9ybWVkMV9wbmxfc2V0MTQsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICBOb2lzeUluZm9ybWVkMl9wbmwgPC0gc2FwcGx5KE5vaXN5SW5mb3JtZWQyX3BubF9zZXQxNCwgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIE5vaXN5MV9wbmwgPC0gc2FwcGx5KE5vaXN5MV9wbmxfc2V0MTQsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICBOb2lzeTJfcG5sIDwtIHNhcHBseShOb2lzeTJfcG5sX3NldDE0LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgbXJfcG5sIDwtIHNhcHBseShtcl9wbmxfc2V0MTQsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICAKICAgICMgQ2FsY3VsYXRlIHRoZSBhdmVyYWdlIG9mIFRydWUgYW5kIEV4cGVjdGVkIHZhbHVlcyBmb3IgdGhlIGktdGggcG9zaXRpb24KICAgIGF2ZXJhZ2VfTU1fcG5sW2ksIG5dIDwtIG1lYW4oTU1fcG5sLCBuYS5ybSA9IFRSVUUpCiAgICBhdmVyYWdlX0luZm9ybWVkX3BubFtpLCBuXSA8LSBtZWFuKEluZm9ybWVkX3BubCwgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9Ob2lzeUluZm9ybWVkMV9wbmxbaSwgbl0gPC0gbWVhbihOb2lzeUluZm9ybWVkMV9wbmwsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfTm9pc3lJbmZvcm1lZDJfcG5sW2ksIG5dIDwtIG1lYW4oTm9pc3lJbmZvcm1lZDJfcG5sLCBuYS5ybSA9IFRSVUUpCiAgICBhdmVyYWdlX05vaXN5MV9wbmxbaSwgbl0gPC0gbWVhbihOb2lzeTFfcG5sLCBuYS5ybSA9IFRSVUUpCiAgICBhdmVyYWdlX05vaXN5Ml9wbmxbaSwgbl0gPC0gbWVhbihOb2lzeTJfcG5sLCBuYS5ybSA9IFRSVUUpCiAgICBhdmVyYWdlX21yX3BubFtpLCBuXSA8LSBtZWFuKG1yX3BubCwgbmEucm0gPSBUUlVFKQogIH0KfQoKIyBDYWxjdWxhdGUgdGhlIG92ZXJhbGwgYXZlcmFnZSBmb3IgZWFjaCBwb3NpdGlvbiBhY3Jvc3MgYWxsIHNpbXVsYXRpb25zCm92ZXJhbGxfYXZlcmFnZV9NTV9wbmwgPC0gcm93TWVhbnMoYXZlcmFnZV9NTV9wbmwsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX0luZm9ybWVkX3BubCA8LSByb3dNZWFucyhhdmVyYWdlX0luZm9ybWVkX3BubCwgbmEucm0gPSBUUlVFKQpvdmVyYWxsX2F2ZXJhZ2VfTm9pc3lJbmZvcm1lZDFfcG5sIDwtIHJvd01lYW5zKGF2ZXJhZ2VfTm9pc3lJbmZvcm1lZDFfcG5sLCBuYS5ybSA9IFRSVUUpCm92ZXJhbGxfYXZlcmFnZV9Ob2lzeUluZm9ybWVkMl9wbmwgPC0gcm93TWVhbnMoYXZlcmFnZV9Ob2lzeUluZm9ybWVkMl9wbmwsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX05vaXN5MV9wbmwgPC0gcm93TWVhbnMoYXZlcmFnZV9Ob2lzeTFfcG5sLCBuYS5ybSA9IFRSVUUpCm92ZXJhbGxfYXZlcmFnZV9Ob2lzeTJfcG5sIDwtIHJvd01lYW5zKGF2ZXJhZ2VfTm9pc3kyX3BubCwgbmEucm0gPSBUUlVFKQpvdmVyYWxsX2F2ZXJhZ2VfbXJfcG5sIDwtIHJvd01lYW5zKGF2ZXJhZ2VfbXJfcG5sLCBuYS5ybSA9IFRSVUUpCgojIFBsb3QgdGhlIG92ZXJhbGwgYXZlcmFnZXMKcGxvdChvdmVyYWxsX2F2ZXJhZ2VfTU1fcG5sLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gImJsYWNrIiwgbWFpbiA9ICJPdmVyYWxsIEF2ZXJhZ2UgUE5MIiwgeGxhYiA9ICJQb3NpdGlvbiBpbiBMaXN0IiwgeWxhYiA9ICJWYWx1ZSIsIHlsaW0gPSBjKG1pbihjKG92ZXJhbGxfYXZlcmFnZV9NTV9wbmwsIG92ZXJhbGxfYXZlcmFnZV9JbmZvcm1lZF9wbmwsIG92ZXJhbGxfYXZlcmFnZV9Ob2lzeUluZm9ybWVkMV9wbmwsIG92ZXJhbGxfYXZlcmFnZV9Ob2lzeUluZm9ybWVkMl9wbmwsIG92ZXJhbGxfYXZlcmFnZV9Ob2lzeTFfcG5sLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3kyX3BubCwgb3ZlcmFsbF9hdmVyYWdlX21yX3BubCkpLCBtYXgoYyhvdmVyYWxsX2F2ZXJhZ2VfTU1fcG5sLCBvdmVyYWxsX2F2ZXJhZ2VfSW5mb3JtZWRfcG5sLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3lJbmZvcm1lZDFfcG5sLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3lJbmZvcm1lZDJfcG5sLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3kxX3BubCwgb3ZlcmFsbF9hdmVyYWdlX05vaXN5Ml9wbmwsIG92ZXJhbGxfYXZlcmFnZV9tcl9wbmwpKSkpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9JbmZvcm1lZF9wbmwsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAicmVkIikKbGluZXMob3ZlcmFsbF9hdmVyYWdlX05vaXN5SW5mb3JtZWQxX3BubCwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJncmVlbiIpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9Ob2lzeUluZm9ybWVkMl9wbmwsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAieWVsbG93IikKbGluZXMob3ZlcmFsbF9hdmVyYWdlX05vaXN5MV9wbmwsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAiYmx1ZSIpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9Ob2lzeTJfcG5sLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gInB1cnBsZSIpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9tcl9wbmwsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAib3JhbmdlIikKCiMgQWRkIGxlZ2VuZApsZWdlbmQoImJvdHRvbWxlZnQiLCBsZWdlbmQgPSBjKCJNYXJrZXQgTWFrZXIiLCAiSW5mb3JtZWQiLCAiTm9pc3kgSW5mb3JtZWQgMSIsICJOb2lzeSBJbmZvcm1lZCAyIiwgIk5vaXN5IDEiLCAiTm9pc3kgMiIsICJNZWFuIFJldmVyc2lvbiIpLCBjb2wgPSBjKCJibGFjayIsICJyZWQiLCAiZ3JlZW4iLCAieWVsbG93IiwgImJsdWUiLCAicHVycGxlIiwgIm9yYW5nZSIpLCBsdHkgPSAxLCBjZXggPSAwLjgpCmBgYAoKYGBge3J9CiMgSW5pdGlhbGl6ZSBtYXRyaWNlcyB0byBzdG9yZSBhdmVyYWdlcyBmb3IgZWFjaCBwb3NpdGlvbgphdmVyYWdlX01NX3BvcyA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKYXZlcmFnZV9JbmZvcm1lZF9wb3MgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfTm9pc3lJbmZvcm1lZDFfcG9zIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX05vaXN5SW5mb3JtZWQyX3BvcyA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKYXZlcmFnZV9Ob2lzeTFfcG9zIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX05vaXN5Ml9wb3MgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfbXJfcG9zIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQoKIyBMb29wIHRocm91Z2ggZWFjaCBzaW11bGF0aW9uIChuKQpmb3IgKG4gaW4gMToxMCkgewoKICBNTV9wb3Nfc2V0MTQgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzE0W24sIDddKSksICIsICIpCgogIEluZm9ybWVkX3Bvc19zZXQxNCA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfMTRbbiwgOV0pKSwgIiwgIikKICAKICBOb2lzeUluZm9ybWVkMV9wb3Nfc2V0MTQgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzE0W24sIDExXSkpLCAiLCAiKQogIAogIE5vaXN5SW5mb3JtZWQyX3Bvc19zZXQxNCA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfMTRbbiwgMTNdKSksICIsICIpCiAgCiAgTm9pc3kxX3Bvc19zZXQxNCA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfMTRbbiwgMTVdKSksICIsICIpCiAgCiAgTm9pc3kyX3Bvc19zZXQxNCA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfMTRbbiwgMTddKSksICIsICIpCiAgCiAgbXJfcG9zX3NldDE0IDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c18xNFtuLCAxOV0pKSwgIiwgIikKICAKICAjIExvb3AgdGhyb3VnaCBlYWNoIHBvc2l0aW9uIChpKQogIGZvciAoaSBpbiAxOjEwMCkgewogICAgIyBFeHRyYWN0IFRydWUgYW5kIEV4cGVjdGVkIHZhbHVlcyBmb3IgdGhlIGktdGggcG9zaXRpb24KICAgIE1NX3BvcyA8LSBzYXBwbHkoTU1fcG9zX3NldDE0LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgSW5mb3JtZWRfcG9zIDwtIHNhcHBseShJbmZvcm1lZF9wb3Nfc2V0MTQsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICBOb2lzeUluZm9ybWVkMV9wb3MgPC0gc2FwcGx5KE5vaXN5SW5mb3JtZWQxX3Bvc19zZXQxNCwgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIE5vaXN5SW5mb3JtZWQyX3BvcyA8LSBzYXBwbHkoTm9pc3lJbmZvcm1lZDJfcG9zX3NldDE0LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgTm9pc3kxX3BvcyA8LSBzYXBwbHkoTm9pc3kxX3Bvc19zZXQxNCwgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIE5vaXN5Ml9wb3MgPC0gc2FwcGx5KE5vaXN5Ml9wb3Nfc2V0MTQsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICBtcl9wb3MgPC0gc2FwcGx5KG1yX3Bvc19zZXQxNCwgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIAogICAgIyBDYWxjdWxhdGUgdGhlIGF2ZXJhZ2Ugb2YgVHJ1ZSBhbmQgRXhwZWN0ZWQgdmFsdWVzIGZvciB0aGUgaS10aCBwb3NpdGlvbgogICAgYXZlcmFnZV9NTV9wb3NbaSwgbl0gPC0gbWVhbihNTV9wb3MsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfSW5mb3JtZWRfcG9zW2ksIG5dIDwtIG1lYW4oSW5mb3JtZWRfcG9zLCBuYS5ybSA9IFRSVUUpCiAgICBhdmVyYWdlX05vaXN5SW5mb3JtZWQxX3Bvc1tpLCBuXSA8LSBtZWFuKE5vaXN5SW5mb3JtZWQxX3BvcywgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9Ob2lzeUluZm9ybWVkMl9wb3NbaSwgbl0gPC0gbWVhbihOb2lzeUluZm9ybWVkMl9wb3MsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfTm9pc3kxX3Bvc1tpLCBuXSA8LSBtZWFuKE5vaXN5MV9wb3MsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfTm9pc3kyX3Bvc1tpLCBuXSA8LSBtZWFuKE5vaXN5Ml9wb3MsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfbXJfcG9zW2ksIG5dIDwtIG1lYW4obXJfcG9zLCBuYS5ybSA9IFRSVUUpCiAgfQp9CgojIENhbGN1bGF0ZSB0aGUgb3ZlcmFsbCBhdmVyYWdlIGZvciBlYWNoIHBvc2l0aW9uIGFjcm9zcyBhbGwgc2ltdWxhdGlvbnMKb3ZlcmFsbF9hdmVyYWdlX01NX3BvcyA8LSByb3dNZWFucyhhdmVyYWdlX01NX3BvcywgbmEucm0gPSBUUlVFKQpvdmVyYWxsX2F2ZXJhZ2VfSW5mb3JtZWRfcG9zIDwtIHJvd01lYW5zKGF2ZXJhZ2VfSW5mb3JtZWRfcG9zLCBuYS5ybSA9IFRSVUUpCm92ZXJhbGxfYXZlcmFnZV9Ob2lzeUluZm9ybWVkMV9wb3MgPC0gcm93TWVhbnMoYXZlcmFnZV9Ob2lzeUluZm9ybWVkMV9wb3MsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX05vaXN5SW5mb3JtZWQyX3BvcyA8LSByb3dNZWFucyhhdmVyYWdlX05vaXN5SW5mb3JtZWQyX3BvcywgbmEucm0gPSBUUlVFKQpvdmVyYWxsX2F2ZXJhZ2VfTm9pc3kxX3BvcyA8LSByb3dNZWFucyhhdmVyYWdlX05vaXN5MV9wb3MsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX05vaXN5Ml9wb3MgPC0gcm93TWVhbnMoYXZlcmFnZV9Ob2lzeTJfcG9zLCBuYS5ybSA9IFRSVUUpCm92ZXJhbGxfYXZlcmFnZV9tcl9wb3MgPC0gcm93TWVhbnMoYXZlcmFnZV9tcl9wb3MsIG5hLnJtID0gVFJVRSkKCiMgUGxvdCB0aGUgb3ZlcmFsbCBhdmVyYWdlcwpwbG90KG92ZXJhbGxfYXZlcmFnZV9NTV9wb3MsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAiYmxhY2siLCBtYWluID0gIk92ZXJhbGwgQXZlcmFnZSBQb3NpdGlvbiIsIHhsYWIgPSAiUG9zaXRpb24gaW4gTGlzdCIsIHlsYWIgPSAiVmFsdWUiLCB5bGltID0gYyhtaW4oYyhvdmVyYWxsX2F2ZXJhZ2VfTU1fcG9zLCBvdmVyYWxsX2F2ZXJhZ2VfSW5mb3JtZWRfcG9zLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3lJbmZvcm1lZDFfcG9zLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3lJbmZvcm1lZDJfcG9zLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3kxX3Bvcywgb3ZlcmFsbF9hdmVyYWdlX05vaXN5Ml9wb3MsIG92ZXJhbGxfYXZlcmFnZV9tcl9wb3MpKSwgbWF4KGMob3ZlcmFsbF9hdmVyYWdlX01NX3Bvcywgb3ZlcmFsbF9hdmVyYWdlX0luZm9ybWVkX3Bvcywgb3ZlcmFsbF9hdmVyYWdlX05vaXN5SW5mb3JtZWQxX3Bvcywgb3ZlcmFsbF9hdmVyYWdlX05vaXN5SW5mb3JtZWQyX3Bvcywgb3ZlcmFsbF9hdmVyYWdlX05vaXN5MV9wb3MsIG92ZXJhbGxfYXZlcmFnZV9Ob2lzeTJfcG9zLCBvdmVyYWxsX2F2ZXJhZ2VfbXJfcG9zKSkpKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfSW5mb3JtZWRfcG9zLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gInJlZCIpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9Ob2lzeUluZm9ybWVkMV9wb3MsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAiZ3JlZW4iKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfTm9pc3lJbmZvcm1lZDJfcG9zLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gInllbGxvdyIpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9Ob2lzeTFfcG9zLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gImJsdWUiKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfTm9pc3kyX3BvcywgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJwdXJwbGUiKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfbXJfcG9zLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gIm9yYW5nZSIpCgojIEFkZCBsZWdlbmQKbGVnZW5kKCJib3R0b21sZWZ0IiwgbGVnZW5kID0gYygiTWFya2V0IE1ha2VyIiwgIkluZm9ybWVkIiwgIk5vaXN5IEluZm9ybWVkIDEiLCAiTm9pc3kgSW5mb3JtZWQgMiIsICJOb2lzeSAxIiwgIk5vaXN5IDIiLCAiTWVhbiBSZXZlcnNpb24iKSwgY29sID0gYygiYmxhY2siLCAicmVkIiwgImdyZWVuIiwgInllbGxvdyIsICJibHVlIiwgInB1cnBsZSIsICJvcmFuZ2UiKSwgbHR5ID0gMSwgY2V4ID0gMC44KQpgYGAKCgoKIyMgc2V0MTUgICgxIGluZm9ybWVkICsgMiBub2lzeSBpbmZvcm1lZCArIDIgbm9pc3kgKyAxIG1vbm1lbnR1bSkKCmBgYHtyfQojIEluaXRpYWxpemUgbWF0cmljZXMgdG8gc3RvcmUgYXZlcmFnZXMgZm9yIGVhY2ggcG9zaXRpb24KYXZlcmFnZV9iaWQgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfYXNrIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQoKIyBMb29wIHRocm91Z2ggZWFjaCBzaW11bGF0aW9uIChuKQpmb3IgKG4gaW4gMToxMCkgewogICMgRXh0cmFjdCBUcnVlIHZhbHVlcyBmcm9tIHRoZSBhZ2dyZWdhdGVkX3Jlc3VsdHNfNCBkYXRhZnJhbWUKICBCaWRzX3NldDE1IDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c18xNVtuLCA0XSkpLCAiLCAiKQogIAogICMgRXh0cmFjdCBFeHBlY3RlZCB2YWx1ZXMgZnJvbSB0aGUgYWdncmVnYXRlZF9yZXN1bHRzXzQgZGF0YWZyYW1lCiAgQXNrc19zZXQxNSA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfMTVbbiwgNV0pKSwgIiwgIikKICAKICAjIExvb3AgdGhyb3VnaCBlYWNoIHBvc2l0aW9uIChpKQogIGZvciAoaSBpbiAxOjEwMCkgewogICAgIyBFeHRyYWN0IFRydWUgYW5kIEV4cGVjdGVkIHZhbHVlcyBmb3IgdGhlIGktdGggcG9zaXRpb24KICAgIEJpZHMgPC0gc2FwcGx5KEJpZHNfc2V0MTUsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICBBc2tzIDwtIHNhcHBseShBc2tzX3NldDE1LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgCiAgICAjIENhbGN1bGF0ZSB0aGUgYXZlcmFnZSBvZiBUcnVlIGFuZCBFeHBlY3RlZCB2YWx1ZXMgZm9yIHRoZSBpLXRoIHBvc2l0aW9uCiAgICBhdmVyYWdlX2JpZFtpLCBuXSA8LSBtZWFuKEJpZHMsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfYXNrW2ksIG5dIDwtIG1lYW4oQXNrcywgbmEucm0gPSBUUlVFKQogIH0KfQoKIyBDYWxjdWxhdGUgdGhlIG92ZXJhbGwgYXZlcmFnZSBmb3IgZWFjaCBwb3NpdGlvbiBhY3Jvc3MgYWxsIHNpbXVsYXRpb25zCm92ZXJhbGxfYXZlcmFnZV9iaWQgPC0gcm93TWVhbnMoYXZlcmFnZV9iaWQsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX2FzayA8LSByb3dNZWFucyhhdmVyYWdlX2FzaywgbmEucm0gPSBUUlVFKQoKIyMgVHJ1ZSBWYWx1ZQojIEluaXRpYWxpemUgbWF0cmljZXMgdG8gc3RvcmUgYXZlcmFnZXMgZm9yIGVhY2ggcG9zaXRpb24KYXZlcmFnZV90cnVlIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX2V4cGVjdGVkIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQoKIyBMb29wIHRocm91Z2ggZWFjaCBzaW11bGF0aW9uIChuKQpmb3IgKG4gaW4gMToxMCkgewogICMgRXh0cmFjdCBUcnVlIHZhbHVlcyBmcm9tIHRoZSBhZ2dyZWdhdGVkX3Jlc3VsdHNfNCBkYXRhZnJhbWUKICBUcnVlVmFsdWVzX3NldDE1IDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c18xNVtuLCAyXSkpLCAiLCAiKQogIAogICMgRXh0cmFjdCBFeHBlY3RlZCB2YWx1ZXMgZnJvbSB0aGUgYWdncmVnYXRlZF9yZXN1bHRzXzQgZGF0YWZyYW1lCiAgRXhwZWN0ZWRWYWx1ZXNfc2V0MTUgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzE1W24sIDNdKSksICIsICIpCiAgCiAgIyBMb29wIHRocm91Z2ggZWFjaCBwb3NpdGlvbiAoaSkKICBmb3IgKGkgaW4gMToxMDApIHsKICAgICMgRXh0cmFjdCBUcnVlIGFuZCBFeHBlY3RlZCB2YWx1ZXMgZm9yIHRoZSBpLXRoIHBvc2l0aW9uCiAgICBUcnVlX3ZhbHVlcyA8LSBzYXBwbHkoVHJ1ZVZhbHVlc19zZXQxNSwgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIEV4cGVjdGVkX3ZhbHVlcyA8LSBzYXBwbHkoRXhwZWN0ZWRWYWx1ZXNfc2V0MTUsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICAKICAgICMgQ2FsY3VsYXRlIHRoZSBhdmVyYWdlIG9mIFRydWUgYW5kIEV4cGVjdGVkIHZhbHVlcyBmb3IgdGhlIGktdGggcG9zaXRpb24KICAgIGF2ZXJhZ2VfdHJ1ZVtpLCBuXSA8LSBtZWFuKFRydWVfdmFsdWVzLCBuYS5ybSA9IFRSVUUpCiAgICBhdmVyYWdlX2V4cGVjdGVkW2ksIG5dIDwtIG1lYW4oRXhwZWN0ZWRfdmFsdWVzLCBuYS5ybSA9IFRSVUUpCiAgfQp9CgojIENhbGN1bGF0ZSB0aGUgb3ZlcmFsbCBhdmVyYWdlIGZvciBlYWNoIHBvc2l0aW9uIGFjcm9zcyBhbGwgc2ltdWxhdGlvbnMKb3ZlcmFsbF9hdmVyYWdlX3RydWUgPC0gcm93TWVhbnMoYXZlcmFnZV90cnVlLCBuYS5ybSA9IFRSVUUpCm92ZXJhbGxfYXZlcmFnZV9leHBlY3RlZCA8LSByb3dNZWFucyhhdmVyYWdlX2V4cGVjdGVkLCBuYS5ybSA9IFRSVUUpCgojIFBsb3QgdGhlIG92ZXJhbGwgYXZlcmFnZXMKI3Bsb3Qob3ZlcmFsbF9hdmVyYWdlX3RydWUsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAiYmx1ZSIsIG1haW4gPSAiT3ZlcmFsbCBBdmVyYWdlIG9mIFRydWUgdnMgRXhwZWN0ZWQgVmFsdWVzIiwgeGxhYiA9ICJQb3NpdGlvbiBpbiBMaXN0IiwgeWxhYiA9ICJWYWx1ZSIsIHlsaW0gPSBjKG1pbihjKG92ZXJhbGxfYXZlcmFnZV90cnVlLCBvdmVyYWxsX2F2ZXJhZ2VfZXhwZWN0ZWQpKSwgbWF4KGMob3ZlcmFsbF9hdmVyYWdlX3RydWUsIG92ZXJhbGxfYXZlcmFnZV9leHBlY3RlZCkpKSkKI2xpbmVzKG92ZXJhbGxfYXZlcmFnZV9leHBlY3RlZCwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJyZWQiKQojbGVnZW5kKCJ0b3ByaWdodCIsIGxlZ2VuZCA9IGMoIlRydWUgVmFsdWVzIiwgIkV4cGVjdGVkIFZhbHVlcyIpLCBjb2wgPSBjKCJibHVlIiwgInJlZCIpLCBsdHkgPSAxLCBjZXggPSAwLjgpCgojIFBsb3QgdGhlIG92ZXJhbGwgYXZlcmFnZXMKcGxvdChvdmVyYWxsX2F2ZXJhZ2VfYmlkLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gImJsdWUiLCBtYWluID0gIk92ZXJhbGwgQXZlcmFnZSBvZiBCaWRzIHZzIEFza3MgJiBUcnVlIHZzIEV4cGVjdGVkIFZhbHVlcyIsIHhsYWIgPSAiUG9zaXRpb24gaW4gTGlzdCIsIHlsYWIgPSAiVmFsdWUiLCB5bGltID0gYyhtaW4oYyhvdmVyYWxsX2F2ZXJhZ2VfYmlkLCBvdmVyYWxsX2F2ZXJhZ2VfYXNrLCBvdmVyYWxsX2F2ZXJhZ2VfdHJ1ZSwgb3ZlcmFsbF9hdmVyYWdlX2V4cGVjdGVkKSksIG1heChjKG92ZXJhbGxfYXZlcmFnZV9iaWQsIG92ZXJhbGxfYXZlcmFnZV9hc2ssIG92ZXJhbGxfYXZlcmFnZV90cnVlLCBvdmVyYWxsX2F2ZXJhZ2VfZXhwZWN0ZWQpKSkpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9hc2ssIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAicmVkIikKbGluZXMob3ZlcmFsbF9hdmVyYWdlX3RydWUsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAiZ3JlZW4iKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfZXhwZWN0ZWQsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAicHVycGxlIikKbGVnZW5kKCJib3R0b21sZWZ0IiwgbGVnZW5kID0gYygiQmlkcyIsICJBc2tzIiwgIlRydWUgVmFsdWUiLCAiRXhwZWN0ZWQgVmFsdWUiKSwgY29sID0gYygiYmx1ZSIsICJyZWQiLCAiZ3JlZW4iLCAicHVycGxlIiksIGx0eSA9IDEsIGNleCA9IDAuOCkKYGBgCgpgYGB7cn0KIyBJbml0aWFsaXplIG1hdHJpY2VzIHRvIHN0b3JlIGF2ZXJhZ2VzIGZvciBlYWNoIHBvc2l0aW9uCmF2ZXJhZ2VfTU1fcG5sIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX0luZm9ybWVkX3BubCA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKYXZlcmFnZV9Ob2lzeUluZm9ybWVkMV9wbmwgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfTm9pc3lJbmZvcm1lZDJfcG5sIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX05vaXN5MV9wbmwgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfTm9pc3kyX3BubCA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKYXZlcmFnZV9tb21fcG5sIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQoKIyBMb29wIHRocm91Z2ggZWFjaCBzaW11bGF0aW9uIChuKQpmb3IgKG4gaW4gMToxMCkgewoKICBNTV9wbmxfc2V0MTUgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzE1W24sIDZdKSksICIsICIpCgogIEluZm9ybWVkX3BubF9zZXQxNSA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfMTVbbiwgOF0pKSwgIiwgIikKICAKICBOb2lzeUluZm9ybWVkMV9wbmxfc2V0MTUgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzE1W24sIDEwXSkpLCAiLCAiKQogIAogIE5vaXN5SW5mb3JtZWQyX3BubF9zZXQxNSA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfMTVbbiwgMTJdKSksICIsICIpCiAgCiAgTm9pc3kxX3BubF9zZXQxNSA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfMTVbbiwgMTRdKSksICIsICIpCiAgCiAgTm9pc3kyX3BubF9zZXQxNSA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfMTVbbiwgMTZdKSksICIsICIpCiAgCiAgbW9tX3BubF9zZXQxNSA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfMTVbbiwgMThdKSksICIsICIpCiAgCiAgIyBMb29wIHRocm91Z2ggZWFjaCBwb3NpdGlvbiAoaSkKICBmb3IgKGkgaW4gMToxMDApIHsKICAgICMgRXh0cmFjdCBUcnVlIGFuZCBFeHBlY3RlZCB2YWx1ZXMgZm9yIHRoZSBpLXRoIHBvc2l0aW9uCiAgICBNTV9wbmwgPC0gc2FwcGx5KE1NX3BubF9zZXQxNSwgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIEluZm9ybWVkX3BubCA8LSBzYXBwbHkoSW5mb3JtZWRfcG5sX3NldDE1LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgTm9pc3lJbmZvcm1lZDFfcG5sIDwtIHNhcHBseShOb2lzeUluZm9ybWVkMV9wbmxfc2V0MTUsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICBOb2lzeUluZm9ybWVkMl9wbmwgPC0gc2FwcGx5KE5vaXN5SW5mb3JtZWQyX3BubF9zZXQxNSwgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIE5vaXN5MV9wbmwgPC0gc2FwcGx5KE5vaXN5MV9wbmxfc2V0MTUsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICBOb2lzeTJfcG5sIDwtIHNhcHBseShOb2lzeTJfcG5sX3NldDE1LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgbW9tX3BubCA8LSBzYXBwbHkobW9tX3BubF9zZXQxNSwgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIAogICAgIyBDYWxjdWxhdGUgdGhlIGF2ZXJhZ2Ugb2YgVHJ1ZSBhbmQgRXhwZWN0ZWQgdmFsdWVzIGZvciB0aGUgaS10aCBwb3NpdGlvbgogICAgYXZlcmFnZV9NTV9wbmxbaSwgbl0gPC0gbWVhbihNTV9wbmwsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfSW5mb3JtZWRfcG5sW2ksIG5dIDwtIG1lYW4oSW5mb3JtZWRfcG5sLCBuYS5ybSA9IFRSVUUpCiAgICBhdmVyYWdlX05vaXN5SW5mb3JtZWQxX3BubFtpLCBuXSA8LSBtZWFuKE5vaXN5SW5mb3JtZWQxX3BubCwgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9Ob2lzeUluZm9ybWVkMl9wbmxbaSwgbl0gPC0gbWVhbihOb2lzeUluZm9ybWVkMl9wbmwsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfTm9pc3kxX3BubFtpLCBuXSA8LSBtZWFuKE5vaXN5MV9wbmwsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfTm9pc3kyX3BubFtpLCBuXSA8LSBtZWFuKE5vaXN5Ml9wbmwsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfbW9tX3BubFtpLCBuXSA8LSBtZWFuKG1vbV9wbmwsIG5hLnJtID0gVFJVRSkKICB9Cn0KCiMgQ2FsY3VsYXRlIHRoZSBvdmVyYWxsIGF2ZXJhZ2UgZm9yIGVhY2ggcG9zaXRpb24gYWNyb3NzIGFsbCBzaW11bGF0aW9ucwpvdmVyYWxsX2F2ZXJhZ2VfTU1fcG5sIDwtIHJvd01lYW5zKGF2ZXJhZ2VfTU1fcG5sLCBuYS5ybSA9IFRSVUUpCm92ZXJhbGxfYXZlcmFnZV9JbmZvcm1lZF9wbmwgPC0gcm93TWVhbnMoYXZlcmFnZV9JbmZvcm1lZF9wbmwsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX05vaXN5SW5mb3JtZWQxX3BubCA8LSByb3dNZWFucyhhdmVyYWdlX05vaXN5SW5mb3JtZWQxX3BubCwgbmEucm0gPSBUUlVFKQpvdmVyYWxsX2F2ZXJhZ2VfTm9pc3lJbmZvcm1lZDJfcG5sIDwtIHJvd01lYW5zKGF2ZXJhZ2VfTm9pc3lJbmZvcm1lZDJfcG5sLCBuYS5ybSA9IFRSVUUpCm92ZXJhbGxfYXZlcmFnZV9Ob2lzeTFfcG5sIDwtIHJvd01lYW5zKGF2ZXJhZ2VfTm9pc3kxX3BubCwgbmEucm0gPSBUUlVFKQpvdmVyYWxsX2F2ZXJhZ2VfTm9pc3kyX3BubCA8LSByb3dNZWFucyhhdmVyYWdlX05vaXN5Ml9wbmwsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX21vbV9wbmwgPC0gcm93TWVhbnMoYXZlcmFnZV9tb21fcG5sLCBuYS5ybSA9IFRSVUUpCgojIFBsb3QgdGhlIG92ZXJhbGwgYXZlcmFnZXMKcGxvdChvdmVyYWxsX2F2ZXJhZ2VfTU1fcG5sLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gImJsYWNrIiwgbWFpbiA9ICJPdmVyYWxsIEF2ZXJhZ2UgUE5MIiwgeGxhYiA9ICJQb3NpdGlvbiBpbiBMaXN0IiwgeWxhYiA9ICJWYWx1ZSIsIHlsaW0gPSBjKG1pbihjKG92ZXJhbGxfYXZlcmFnZV9NTV9wbmwsIG92ZXJhbGxfYXZlcmFnZV9JbmZvcm1lZF9wbmwsIG92ZXJhbGxfYXZlcmFnZV9Ob2lzeUluZm9ybWVkMV9wbmwsIG92ZXJhbGxfYXZlcmFnZV9Ob2lzeUluZm9ybWVkMl9wbmwsIG92ZXJhbGxfYXZlcmFnZV9Ob2lzeTFfcG5sLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3kyX3BubCwgb3ZlcmFsbF9hdmVyYWdlX21vbV9wbmwpKSwgbWF4KGMob3ZlcmFsbF9hdmVyYWdlX01NX3BubCwgb3ZlcmFsbF9hdmVyYWdlX0luZm9ybWVkX3BubCwgb3ZlcmFsbF9hdmVyYWdlX05vaXN5SW5mb3JtZWQxX3BubCwgb3ZlcmFsbF9hdmVyYWdlX05vaXN5SW5mb3JtZWQyX3BubCwgb3ZlcmFsbF9hdmVyYWdlX05vaXN5MV9wbmwsIG92ZXJhbGxfYXZlcmFnZV9Ob2lzeTJfcG5sLCBvdmVyYWxsX2F2ZXJhZ2VfbW9tX3BubCkpKSkKbGluZXMob3ZlcmFsbF9hdmVyYWdlX0luZm9ybWVkX3BubCwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJyZWQiKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfTm9pc3lJbmZvcm1lZDFfcG5sLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gImdyZWVuIikKbGluZXMob3ZlcmFsbF9hdmVyYWdlX05vaXN5SW5mb3JtZWQyX3BubCwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJ5ZWxsb3ciKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfTm9pc3kxX3BubCwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJibHVlIikKbGluZXMob3ZlcmFsbF9hdmVyYWdlX05vaXN5Ml9wbmwsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAicHVycGxlIikKbGluZXMob3ZlcmFsbF9hdmVyYWdlX21vbV9wbmwsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAib3JhbmdlIikKCiMgQWRkIGxlZ2VuZApsZWdlbmQoImJvdHRvbWxlZnQiLCBsZWdlbmQgPSBjKCJNYXJrZXQgTWFrZXIiLCAiSW5mb3JtZWQiLCAiTm9pc3kgSW5mb3JtZWQgMSIsICJOb2lzeSBJbmZvcm1lZCAyIiwgIk5vaXN5IDEiLCAiTm9pc3kgMiIsICJNb21lbnR1bSIpLCBjb2wgPSBjKCJibGFjayIsICJyZWQiLCAiZ3JlZW4iLCAieWVsbG93IiwgImJsdWUiLCAicHVycGxlIiwgIm9yYW5nZSIpLCBsdHkgPSAxLCBjZXggPSAwLjgpCmBgYAoKCgoKCmBgYHtyfQojIEluaXRpYWxpemUgbWF0cmljZXMgdG8gc3RvcmUgYXZlcmFnZXMgZm9yIGVhY2ggcG9zaXRpb24KYXZlcmFnZV9NTV9wb3MgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfSW5mb3JtZWRfcG9zIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX05vaXN5SW5mb3JtZWQxX3BvcyA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKYXZlcmFnZV9Ob2lzeUluZm9ybWVkMl9wb3MgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfTm9pc3kxX3BvcyA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKYXZlcmFnZV9Ob2lzeTJfcG9zIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX21vbV9wb3MgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCgojIExvb3AgdGhyb3VnaCBlYWNoIHNpbXVsYXRpb24gKG4pCmZvciAobiBpbiAxOjEwKSB7CgogIE1NX3Bvc19zZXQxNSA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfMTVbbiwgN10pKSwgIiwgIikKCiAgSW5mb3JtZWRfcG9zX3NldDE1IDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c18xNVtuLCA5XSkpLCAiLCAiKQogIAogIE5vaXN5SW5mb3JtZWQxX3Bvc19zZXQxNSA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfMTVbbiwgMTFdKSksICIsICIpCiAgCiAgTm9pc3lJbmZvcm1lZDJfcG9zX3NldDE1IDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c18xNVtuLCAxM10pKSwgIiwgIikKICAKICBOb2lzeTFfcG9zX3NldDE1IDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c18xNVtuLCAxNV0pKSwgIiwgIikKICAKICBOb2lzeTJfcG9zX3NldDE1IDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c18xNVtuLCAxN10pKSwgIiwgIikKICAKICBtb21fcG9zX3NldDE1IDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c18xNVtuLCAxOV0pKSwgIiwgIikKICAKICAjIExvb3AgdGhyb3VnaCBlYWNoIHBvc2l0aW9uIChpKQogIGZvciAoaSBpbiAxOjEwMCkgewogICAgIyBFeHRyYWN0IFRydWUgYW5kIEV4cGVjdGVkIHZhbHVlcyBmb3IgdGhlIGktdGggcG9zaXRpb24KICAgIE1NX3BvcyA8LSBzYXBwbHkoTU1fcG9zX3NldDE1LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgSW5mb3JtZWRfcG9zIDwtIHNhcHBseShJbmZvcm1lZF9wb3Nfc2V0MTUsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICBOb2lzeUluZm9ybWVkMV9wb3MgPC0gc2FwcGx5KE5vaXN5SW5mb3JtZWQxX3Bvc19zZXQxNSwgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIE5vaXN5SW5mb3JtZWQyX3BvcyA8LSBzYXBwbHkoTm9pc3lJbmZvcm1lZDJfcG9zX3NldDE1LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgTm9pc3kxX3BvcyA8LSBzYXBwbHkoTm9pc3kxX3Bvc19zZXQxNSwgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIE5vaXN5Ml9wb3MgPC0gc2FwcGx5KE5vaXN5Ml9wb3Nfc2V0MTUsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICBtb21fcG9zIDwtIHNhcHBseShtb21fcG9zX3NldDE1LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgCiAgICAjIENhbGN1bGF0ZSB0aGUgYXZlcmFnZSBvZiBUcnVlIGFuZCBFeHBlY3RlZCB2YWx1ZXMgZm9yIHRoZSBpLXRoIHBvc2l0aW9uCiAgICBhdmVyYWdlX01NX3Bvc1tpLCBuXSA8LSBtZWFuKE1NX3BvcywgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9JbmZvcm1lZF9wb3NbaSwgbl0gPC0gbWVhbihJbmZvcm1lZF9wb3MsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfTm9pc3lJbmZvcm1lZDFfcG9zW2ksIG5dIDwtIG1lYW4oTm9pc3lJbmZvcm1lZDFfcG9zLCBuYS5ybSA9IFRSVUUpCiAgICBhdmVyYWdlX05vaXN5SW5mb3JtZWQyX3Bvc1tpLCBuXSA8LSBtZWFuKE5vaXN5SW5mb3JtZWQyX3BvcywgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9Ob2lzeTFfcG9zW2ksIG5dIDwtIG1lYW4oTm9pc3kxX3BvcywgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9Ob2lzeTJfcG9zW2ksIG5dIDwtIG1lYW4oTm9pc3kyX3BvcywgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9tb21fcG9zW2ksIG5dIDwtIG1lYW4obW9tX3BvcywgbmEucm0gPSBUUlVFKQogIH0KfQoKIyBDYWxjdWxhdGUgdGhlIG92ZXJhbGwgYXZlcmFnZSBmb3IgZWFjaCBwb3NpdGlvbiBhY3Jvc3MgYWxsIHNpbXVsYXRpb25zCm92ZXJhbGxfYXZlcmFnZV9NTV9wb3MgPC0gcm93TWVhbnMoYXZlcmFnZV9NTV9wb3MsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX0luZm9ybWVkX3BvcyA8LSByb3dNZWFucyhhdmVyYWdlX0luZm9ybWVkX3BvcywgbmEucm0gPSBUUlVFKQpvdmVyYWxsX2F2ZXJhZ2VfTm9pc3lJbmZvcm1lZDFfcG9zIDwtIHJvd01lYW5zKGF2ZXJhZ2VfTm9pc3lJbmZvcm1lZDFfcG9zLCBuYS5ybSA9IFRSVUUpCm92ZXJhbGxfYXZlcmFnZV9Ob2lzeUluZm9ybWVkMl9wb3MgPC0gcm93TWVhbnMoYXZlcmFnZV9Ob2lzeUluZm9ybWVkMl9wb3MsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX05vaXN5MV9wb3MgPC0gcm93TWVhbnMoYXZlcmFnZV9Ob2lzeTFfcG9zLCBuYS5ybSA9IFRSVUUpCm92ZXJhbGxfYXZlcmFnZV9Ob2lzeTJfcG9zIDwtIHJvd01lYW5zKGF2ZXJhZ2VfTm9pc3kyX3BvcywgbmEucm0gPSBUUlVFKQpvdmVyYWxsX2F2ZXJhZ2VfbW9tX3BvcyA8LSByb3dNZWFucyhhdmVyYWdlX21vbV9wb3MsIG5hLnJtID0gVFJVRSkKCiMgUGxvdCB0aGUgb3ZlcmFsbCBhdmVyYWdlcwpwbG90KG92ZXJhbGxfYXZlcmFnZV9NTV9wb3MsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAiYmxhY2siLCBtYWluID0gIk92ZXJhbGwgQXZlcmFnZSBQb3NpdGlvbiIsIHhsYWIgPSAiUG9zaXRpb24gaW4gTGlzdCIsIHlsYWIgPSAiVmFsdWUiLCB5bGltID0gYyhtaW4oYyhvdmVyYWxsX2F2ZXJhZ2VfTU1fcG9zLCBvdmVyYWxsX2F2ZXJhZ2VfSW5mb3JtZWRfcG9zLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3lJbmZvcm1lZDFfcG9zLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3lJbmZvcm1lZDJfcG9zLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3kxX3Bvcywgb3ZlcmFsbF9hdmVyYWdlX05vaXN5Ml9wb3MsIG92ZXJhbGxfYXZlcmFnZV9tb21fcG9zKSksIG1heChjKG92ZXJhbGxfYXZlcmFnZV9NTV9wb3MsIG92ZXJhbGxfYXZlcmFnZV9JbmZvcm1lZF9wb3MsIG92ZXJhbGxfYXZlcmFnZV9Ob2lzeUluZm9ybWVkMV9wb3MsIG92ZXJhbGxfYXZlcmFnZV9Ob2lzeUluZm9ybWVkMl9wb3MsIG92ZXJhbGxfYXZlcmFnZV9Ob2lzeTFfcG9zLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3kyX3Bvcywgb3ZlcmFsbF9hdmVyYWdlX21vbV9wb3MpKSkpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9JbmZvcm1lZF9wb3MsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAicmVkIikKbGluZXMob3ZlcmFsbF9hdmVyYWdlX05vaXN5SW5mb3JtZWQxX3BvcywgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJncmVlbiIpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9Ob2lzeUluZm9ybWVkMl9wb3MsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAieWVsbG93IikKbGluZXMob3ZlcmFsbF9hdmVyYWdlX05vaXN5MV9wb3MsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAiYmx1ZSIpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9Ob2lzeTJfcG9zLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gInB1cnBsZSIpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9tb21fcG9zLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gIm9yYW5nZSIpCgojIEFkZCBsZWdlbmQKbGVnZW5kKCJib3R0b21sZWZ0IiwgbGVnZW5kID0gYygiTWFya2V0IE1ha2VyIiwgIkluZm9ybWVkIiwgIk5vaXN5IEluZm9ybWVkIDEiLCAiTm9pc3kgSW5mb3JtZWQgMiIsICJOb2lzeSAxIiwgIk5vaXN5IDIiLCAiTW9tZW50dW0iKSwgY29sID0gYygiYmxhY2siLCAicmVkIiwgImdyZWVuIiwgInllbGxvdyIsICJibHVlIiwgInB1cnBsZSIsICJvcmFuZ2UiKSwgbHR5ID0gMSwgY2V4ID0gMC44KQpgYGAKCgoKCgoKCgoKCgoK